mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Get rid of @dynamic_property
This commit is contained in:
parent
846a1a5e9f
commit
f51e63718c
@ -1,6 +1,6 @@
|
|||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 160
|
max-line-length = 160
|
||||||
builtins = _,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext,connect_lambda
|
builtins = _,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext,connect_lambda
|
||||||
ignore = E12,E203,E22,E231,E241,E401,E402,E731,W391,E722,E741,W504
|
ignore = E12,E203,E22,E231,E241,E401,E402,E731,W391,E722,E741,W504
|
||||||
|
|
||||||
[yapf]
|
[yapf]
|
||||||
|
@ -4,9 +4,8 @@ __copyright__ = '2008, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import sys, os, re, time, random, warnings
|
import sys, os, re, time, random, warnings
|
||||||
from polyglot.builtins import (builtins, codepoint_to_chr, iteritems,
|
from polyglot.builtins import (codepoint_to_chr, iteritems,
|
||||||
itervalues, unicode_type, range, filter, hasenv)
|
itervalues, unicode_type, range, filter, hasenv)
|
||||||
builtins.__dict__['dynamic_property'] = lambda func: func(None)
|
|
||||||
from math import floor
|
from math import floor
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
|
@ -1145,17 +1145,14 @@ class DB(object):
|
|||||||
def vacuum(self):
|
def vacuum(self):
|
||||||
self.execute('VACUUM')
|
self.execute('VACUUM')
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def user_version(self):
|
def user_version(self):
|
||||||
doc = 'The user version of this database'
|
'''The user version of this database'''
|
||||||
|
return self.conn.get('pragma user_version;', all=False)
|
||||||
|
|
||||||
def fget(self):
|
@user_version.setter
|
||||||
return self.conn.get('pragma user_version;', all=False)
|
def user_version(self, val):
|
||||||
|
self.execute('pragma user_version=%d'%int(val))
|
||||||
def fset(self, val):
|
|
||||||
self.execute('pragma user_version=%d'%int(val))
|
|
||||||
|
|
||||||
return property(doc=doc, fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def initialize_database(self):
|
def initialize_database(self):
|
||||||
metadata_sqlite = P('metadata_sqlite.sql', data=True,
|
metadata_sqlite = P('metadata_sqlite.sql', data=True,
|
||||||
@ -1252,29 +1249,26 @@ class DB(object):
|
|||||||
def exists_at(cls, path):
|
def exists_at(cls, path):
|
||||||
return path and os.path.exists(os.path.join(path, 'metadata.db'))
|
return path and os.path.exists(os.path.join(path, 'metadata.db'))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def library_id(self):
|
def library_id(self):
|
||||||
doc = ('The UUID for this library. As long as the user only operates'
|
'''The UUID for this library. As long as the user only operates on libraries with calibre, it will be unique'''
|
||||||
' on libraries with calibre, it will be unique')
|
|
||||||
|
|
||||||
def fget(self):
|
if getattr(self, '_library_id_', None) is None:
|
||||||
if getattr(self, '_library_id_', None) is None:
|
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
||||||
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
if ans is None:
|
||||||
if ans is None:
|
ans = str(uuid.uuid4())
|
||||||
ans = str(uuid.uuid4())
|
self.library_id = ans
|
||||||
self.library_id = ans
|
else:
|
||||||
else:
|
self._library_id_ = ans
|
||||||
self._library_id_ = ans
|
return self._library_id_
|
||||||
return self._library_id_
|
|
||||||
|
|
||||||
def fset(self, val):
|
@library_id.setter
|
||||||
self._library_id_ = unicode_type(val)
|
def library_id(self, val):
|
||||||
self.execute('''
|
self._library_id_ = unicode_type(val)
|
||||||
DELETE FROM library_id;
|
self.execute('''
|
||||||
INSERT INTO library_id (uuid) VALUES (?);
|
DELETE FROM library_id;
|
||||||
''', (self._library_id_,))
|
INSERT INTO library_id (uuid) VALUES (?);
|
||||||
|
''', (self._library_id_,))
|
||||||
return property(doc=doc, fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def last_modified(self):
|
def last_modified(self):
|
||||||
''' Return last modified time as a UTC datetime object '''
|
''' Return last modified time as a UTC datetime object '''
|
||||||
|
@ -31,73 +31,55 @@ class FileFormatter(object):
|
|||||||
self.name = file.name
|
self.name = file.name
|
||||||
self.path = file.path
|
self.path = file.path
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def mode_string(self):
|
def mode_string(self):
|
||||||
doc=""" The mode string for this file. There are only two modes read-only and read-write """
|
""" The mode string for this file. There are only two modes read-only and read-write """
|
||||||
|
mode, x = "-", "-"
|
||||||
|
if self.is_dir:
|
||||||
|
mode, x = "d", "x"
|
||||||
|
if self.is_readonly:
|
||||||
|
mode += "r-"+x+"r-"+x+"r-"+x
|
||||||
|
else:
|
||||||
|
mode += "rw"+x+"rw"+x+"rw"+x
|
||||||
|
return mode
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
mode, x = "-", "-"
|
|
||||||
if self.is_dir:
|
|
||||||
mode, x = "d", "x"
|
|
||||||
if self.is_readonly:
|
|
||||||
mode += "r-"+x+"r-"+x+"r-"+x
|
|
||||||
else:
|
|
||||||
mode += "rw"+x+"rw"+x+"rw"+x
|
|
||||||
return mode
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def isdir_name(self):
|
def isdir_name(self):
|
||||||
doc='''Return self.name + '/' if self is a directory'''
|
'''Return self.name + '/' if self is a directory'''
|
||||||
|
name = self.name
|
||||||
|
if self.is_dir:
|
||||||
|
name += '/'
|
||||||
|
return name
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
name = self.name
|
|
||||||
if self.is_dir:
|
|
||||||
name += '/'
|
|
||||||
return name
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def name_in_color(self):
|
def name_in_color(self):
|
||||||
doc=""" The name in ANSI text. Directories are blue, ebooks are green """
|
""" The name in ANSI text. Directories are blue, ebooks are green """
|
||||||
|
cname = self.name
|
||||||
|
blue, green, normal = "", "", ""
|
||||||
|
if self.term:
|
||||||
|
blue, green, normal = self.term.BLUE, self.term.GREEN, self.term.NORMAL
|
||||||
|
if self.is_dir:
|
||||||
|
cname = blue + self.name + normal
|
||||||
|
else:
|
||||||
|
ext = self.name[self.name.rfind("."):]
|
||||||
|
if ext in (".pdf", ".rtf", ".lrf", ".lrx", ".txt"):
|
||||||
|
cname = green + self.name + normal
|
||||||
|
return cname
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
cname = self.name
|
|
||||||
blue, green, normal = "", "", ""
|
|
||||||
if self.term:
|
|
||||||
blue, green, normal = self.term.BLUE, self.term.GREEN, self.term.NORMAL
|
|
||||||
if self.is_dir:
|
|
||||||
cname = blue + self.name + normal
|
|
||||||
else:
|
|
||||||
ext = self.name[self.name.rfind("."):]
|
|
||||||
if ext in (".pdf", ".rtf", ".lrf", ".lrx", ".txt"):
|
|
||||||
cname = green + self.name + normal
|
|
||||||
return cname
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def human_readable_size(self):
|
def human_readable_size(self):
|
||||||
doc=""" File size in human readable form """
|
""" File size in human readable form """
|
||||||
|
return human_readable(self.size)
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
return human_readable(self.size)
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def modification_time(self):
|
def modification_time(self):
|
||||||
doc=""" Last modified time in the Linux ls -l format """
|
""" Last modified time in the Linux ls -l format """
|
||||||
|
return time.strftime("%Y-%m-%d %H:%M", time.localtime(self.wtime))
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
return time.strftime("%Y-%m-%d %H:%M", time.localtime(self.wtime))
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def creation_time(self):
|
def creation_time(self):
|
||||||
doc=""" Last modified time in the Linux ls -l format """
|
""" Last modified time in the Linux ls -l format """
|
||||||
|
return time.strftime("%Y-%m-%d %H:%M", time.localtime(self.ctime))
|
||||||
def fget(self):
|
|
||||||
return time.strftime("%Y-%m-%d %H:%M", time.localtime(self.ctime))
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
|
|
||||||
def info(dev):
|
def info(dev):
|
||||||
|
@ -46,26 +46,21 @@ class Book(Metadata):
|
|||||||
# use lpath because the prefix can change, changing path
|
# use lpath because the prefix can change, changing path
|
||||||
return self.lpath == getattr(other, 'lpath', None)
|
return self.lpath == getattr(other, 'lpath', None)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def db_id(self):
|
def db_id(self):
|
||||||
doc = '''The database id in the application database that this file corresponds to'''
|
'''The database id in the application database that this file corresponds to'''
|
||||||
|
|
||||||
def fget(self):
|
match = re.search(r'_(\d+)$', self.lpath.rpartition('.')[0])
|
||||||
match = re.search(r'_(\d+)$', self.lpath.rpartition('.')[0])
|
if match:
|
||||||
if match:
|
return int(match.group(1))
|
||||||
return int(match.group(1))
|
return None
|
||||||
return None
|
|
||||||
return property(fget=fget, doc=doc)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def title_sorter(self):
|
def title_sorter(self):
|
||||||
doc = '''String to sort the title. If absent, title is returned'''
|
'''String to sort the title. If absent, title is returned'''
|
||||||
|
return title_sort(self.title)
|
||||||
|
|
||||||
def fget(self):
|
@property
|
||||||
return title_sort(self.title)
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def thumbnail(self):
|
def thumbnail(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -169,24 +169,23 @@ class Block(object):
|
|||||||
def height(self):
|
def height(self):
|
||||||
return int(ceil(sum(l if isinstance(l, numbers.Number) else l.boundingRect().height() for l in self.layouts)))
|
return int(ceil(sum(l if isinstance(l, numbers.Number) else l.boundingRect().height() for l in self.layouts)))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def position(self):
|
def position(self):
|
||||||
def fget(self):
|
return self._position
|
||||||
return self._position
|
|
||||||
|
|
||||||
def fset(self, new_pos):
|
@position.setter
|
||||||
(x, y) = new_pos
|
def position(self, new_pos):
|
||||||
self._position = Point(x, y)
|
(x, y) = new_pos
|
||||||
if self.layouts:
|
self._position = Point(x, y)
|
||||||
self.layouts[0].setPosition(QPointF(x, y))
|
if self.layouts:
|
||||||
y += self.layouts[0].boundingRect().height()
|
self.layouts[0].setPosition(QPointF(x, y))
|
||||||
for l in self.layouts[1:]:
|
y += self.layouts[0].boundingRect().height()
|
||||||
if isinstance(l, numbers.Number):
|
for l in self.layouts[1:]:
|
||||||
y += l
|
if isinstance(l, numbers.Number):
|
||||||
else:
|
y += l
|
||||||
l.setPosition(QPointF(x, y))
|
else:
|
||||||
y += l.boundingRect().height()
|
l.setPosition(QPointF(x, y))
|
||||||
return property(fget=fget, fset=fset)
|
y += l.boundingRect().height()
|
||||||
|
|
||||||
def draw(self, painter):
|
def draw(self, painter):
|
||||||
for l in self.layouts:
|
for l in self.layouts:
|
||||||
|
@ -209,37 +209,29 @@ class Tag(object):
|
|||||||
s += " at %08X, contents: %s" % (self.offset, repr(self.contents))
|
s += " at %08X, contents: %s" % (self.offset, repr(self.contents))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def byte(self):
|
def byte(self):
|
||||||
def fget(self):
|
if len(self.contents) != 1:
|
||||||
if len(self.contents) != 1:
|
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
||||||
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
return struct.unpack("<B", self.contents)[0]
|
||||||
return struct.unpack("<B", self.contents)[0]
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def word(self):
|
def word(self):
|
||||||
def fget(self):
|
if len(self.contents) != 2:
|
||||||
if len(self.contents) != 2:
|
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
||||||
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
return struct.unpack("<H", self.contents)[0]
|
||||||
return struct.unpack("<H", self.contents)[0]
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def sword(self):
|
def sword(self):
|
||||||
def fget(self):
|
if len(self.contents) != 2:
|
||||||
if len(self.contents) != 2:
|
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
||||||
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
return struct.unpack("<h", self.contents)[0]
|
||||||
return struct.unpack("<h", self.contents)[0]
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def dword(self):
|
def dword(self):
|
||||||
def fget(self):
|
if len(self.contents) != 4:
|
||||||
if len(self.contents) != 4:
|
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
||||||
raise LRFParseError("Bad parameter for tag ID: %04X" % self.id)
|
return struct.unpack("<I", self.contents)[0]
|
||||||
return struct.unpack("<I", self.contents)[0]
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
def dummy_parser(self, stream):
|
def dummy_parser(self, stream):
|
||||||
raise LRFParseError("Unknown tag at %08X" % stream.tell())
|
raise LRFParseError("Unknown tag at %08X" % stream.tell())
|
||||||
|
@ -193,14 +193,13 @@ class ManifestItem(Resource): # {{{
|
|||||||
res.mime_type = mt
|
res.mime_type = mt
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def media_type(self):
|
def media_type(self):
|
||||||
def fget(self):
|
return self.mime_type
|
||||||
return self.mime_type
|
|
||||||
|
|
||||||
def fset(self, val):
|
@media_type.setter
|
||||||
self.mime_type = val
|
def media_type(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.mime_type = val
|
||||||
|
|
||||||
def __unicode__representation__(self):
|
def __unicode__representation__(self):
|
||||||
return u'<item id="%s" href="%s" media-type="%s" />'%(self.id, self.href(), self.media_type)
|
return u'<item id="%s" href="%s" media-type="%s" />'%(self.id, self.href(), self.media_type)
|
||||||
@ -804,172 +803,155 @@ class OPF(object): # {{{
|
|||||||
for item in self.iterguide():
|
for item in self.iterguide():
|
||||||
item.set('href', get_href(item))
|
item.set('href', get_href(item))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def title(self):
|
def title(self):
|
||||||
# TODO: Add support for EPUB 3 refinements
|
# TODO: Add support for EPUB 3 refinements
|
||||||
|
|
||||||
def fget(self):
|
for elem in self.title_path(self.metadata):
|
||||||
for elem in self.title_path(self.metadata):
|
title = self.get_text(elem)
|
||||||
title = self.get_text(elem)
|
if title and title.strip():
|
||||||
if title and title.strip():
|
return re.sub(r'\s+', ' ', title.strip())
|
||||||
return re.sub(r'\s+', ' ', title.strip())
|
|
||||||
|
|
||||||
def fset(self, val):
|
@title.setter
|
||||||
val = (val or '').strip()
|
def title(self, val):
|
||||||
titles = self.title_path(self.metadata)
|
val = (val or '').strip()
|
||||||
if self.package_version < 3:
|
titles = self.title_path(self.metadata)
|
||||||
# EPUB 3 allows multiple title elements containing sub-titles,
|
if self.package_version < 3:
|
||||||
# series and other things. We all loooove EPUB 3.
|
# EPUB 3 allows multiple title elements containing sub-titles,
|
||||||
for title in titles:
|
# series and other things. We all loooove EPUB 3.
|
||||||
title.getparent().remove(title)
|
for title in titles:
|
||||||
titles = ()
|
title.getparent().remove(title)
|
||||||
if val:
|
titles = ()
|
||||||
title = titles[0] if titles else self.create_metadata_element('title')
|
if val:
|
||||||
title.text = re.sub(r'\s+', ' ', unicode_type(val))
|
title = titles[0] if titles else self.create_metadata_element('title')
|
||||||
|
title.text = re.sub(r'\s+', ' ', unicode_type(val))
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
@property
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def authors(self):
|
def authors(self):
|
||||||
|
ans = []
|
||||||
|
for elem in self.authors_path(self.metadata):
|
||||||
|
ans.extend(string_to_authors(self.get_text(elem)))
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@authors.setter
|
||||||
ans = []
|
def authors(self, val):
|
||||||
for elem in self.authors_path(self.metadata):
|
remove = list(self.authors_path(self.metadata))
|
||||||
ans.extend(string_to_authors(self.get_text(elem)))
|
for elem in remove:
|
||||||
return ans
|
elem.getparent().remove(elem)
|
||||||
|
# Ensure new author element is at the top of the list
|
||||||
|
# for broken implementations that always use the first
|
||||||
|
# <dc:creator> element with no attention to the role
|
||||||
|
for author in reversed(val):
|
||||||
|
elem = self.metadata.makeelement('{%s}creator'%
|
||||||
|
self.NAMESPACES['dc'], nsmap=self.NAMESPACES)
|
||||||
|
elem.tail = '\n'
|
||||||
|
self.metadata.insert(0, elem)
|
||||||
|
elem.set('{%s}role'%self.NAMESPACES['opf'], 'aut')
|
||||||
|
self.set_text(elem, author.strip())
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
remove = list(self.authors_path(self.metadata))
|
|
||||||
for elem in remove:
|
|
||||||
elem.getparent().remove(elem)
|
|
||||||
# Ensure new author element is at the top of the list
|
|
||||||
# for broken implementations that always use the first
|
|
||||||
# <dc:creator> element with no attention to the role
|
|
||||||
for author in reversed(val):
|
|
||||||
elem = self.metadata.makeelement('{%s}creator'%
|
|
||||||
self.NAMESPACES['dc'], nsmap=self.NAMESPACES)
|
|
||||||
elem.tail = '\n'
|
|
||||||
self.metadata.insert(0, elem)
|
|
||||||
elem.set('{%s}role'%self.NAMESPACES['opf'], 'aut')
|
|
||||||
self.set_text(elem, author.strip())
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def author_sort(self):
|
def author_sort(self):
|
||||||
|
matches = self.authors_path(self.metadata)
|
||||||
|
if matches:
|
||||||
|
for match in matches:
|
||||||
|
ans = match.get('{%s}file-as'%self.NAMESPACES['opf'], None)
|
||||||
|
if not ans:
|
||||||
|
ans = match.get('file-as', None)
|
||||||
|
if ans:
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@author_sort.setter
|
||||||
matches = self.authors_path(self.metadata)
|
def author_sort(self, val):
|
||||||
if matches:
|
matches = self.authors_path(self.metadata)
|
||||||
for match in matches:
|
if matches:
|
||||||
ans = match.get('{%s}file-as'%self.NAMESPACES['opf'], None)
|
for key in matches[0].attrib:
|
||||||
if not ans:
|
if key.endswith('file-as'):
|
||||||
ans = match.get('file-as', None)
|
matches[0].attrib.pop(key)
|
||||||
if ans:
|
matches[0].set('{%s}file-as'%self.NAMESPACES['opf'], unicode_type(val))
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
matches = self.authors_path(self.metadata)
|
|
||||||
if matches:
|
|
||||||
for key in matches[0].attrib:
|
|
||||||
if key.endswith('file-as'):
|
|
||||||
matches[0].attrib.pop(key)
|
|
||||||
matches[0].set('{%s}file-as'%self.NAMESPACES['opf'], unicode_type(val))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def tags(self):
|
def tags(self):
|
||||||
|
ans = []
|
||||||
|
for tag in self.tags_path(self.metadata):
|
||||||
|
text = self.get_text(tag)
|
||||||
|
if text and text.strip():
|
||||||
|
ans.extend([x.strip() for x in text.split(',')])
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@tags.setter
|
||||||
ans = []
|
def tags(self, val):
|
||||||
for tag in self.tags_path(self.metadata):
|
for tag in list(self.tags_path(self.metadata)):
|
||||||
text = self.get_text(tag)
|
tag.getparent().remove(tag)
|
||||||
if text and text.strip():
|
for tag in val:
|
||||||
ans.extend([x.strip() for x in text.split(',')])
|
elem = self.create_metadata_element('subject')
|
||||||
return ans
|
self.set_text(elem, unicode_type(tag))
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
for tag in list(self.tags_path(self.metadata)):
|
|
||||||
tag.getparent().remove(tag)
|
|
||||||
for tag in val:
|
|
||||||
elem = self.create_metadata_element('subject')
|
|
||||||
self.set_text(elem, unicode_type(tag))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def pubdate(self):
|
def pubdate(self):
|
||||||
|
ans = None
|
||||||
|
for match in self.pubdate_path(self.metadata):
|
||||||
|
try:
|
||||||
|
val = parse_date(etree.tostring(match, encoding=unicode_type,
|
||||||
|
method='text', with_tail=False).strip())
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
if ans is None or val < ans:
|
||||||
|
ans = val
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@pubdate.setter
|
||||||
ans = None
|
def pubdate(self, val):
|
||||||
for match in self.pubdate_path(self.metadata):
|
least_val = least_elem = None
|
||||||
try:
|
for match in self.pubdate_path(self.metadata):
|
||||||
val = parse_date(etree.tostring(match, encoding=unicode_type,
|
try:
|
||||||
method='text', with_tail=False).strip())
|
cval = parse_date(etree.tostring(match, encoding=unicode_type,
|
||||||
except:
|
method='text', with_tail=False).strip())
|
||||||
continue
|
except:
|
||||||
if ans is None or val < ans:
|
match.getparent().remove(match)
|
||||||
ans = val
|
else:
|
||||||
return ans
|
if not val:
|
||||||
|
|
||||||
def fset(self, val):
|
|
||||||
least_val = least_elem = None
|
|
||||||
for match in self.pubdate_path(self.metadata):
|
|
||||||
try:
|
|
||||||
cval = parse_date(etree.tostring(match, encoding=unicode_type,
|
|
||||||
method='text', with_tail=False).strip())
|
|
||||||
except:
|
|
||||||
match.getparent().remove(match)
|
match.getparent().remove(match)
|
||||||
else:
|
if least_val is None or cval < least_val:
|
||||||
if not val:
|
least_val, least_elem = cval, match
|
||||||
match.getparent().remove(match)
|
|
||||||
if least_val is None or cval < least_val:
|
|
||||||
least_val, least_elem = cval, match
|
|
||||||
|
|
||||||
if val:
|
if val:
|
||||||
if least_val is None:
|
if least_val is None:
|
||||||
least_elem = self.create_metadata_element('date')
|
least_elem = self.create_metadata_element('date')
|
||||||
|
|
||||||
least_elem.attrib.clear()
|
least_elem.attrib.clear()
|
||||||
least_elem.text = isoformat(val)
|
least_elem.text = isoformat(val)
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
@property
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def isbn(self):
|
def isbn(self):
|
||||||
|
for match in self.isbn_path(self.metadata):
|
||||||
|
return self.get_text(match) or None
|
||||||
|
|
||||||
def fget(self):
|
@isbn.setter
|
||||||
for match in self.isbn_path(self.metadata):
|
def isbn(self, val):
|
||||||
return self.get_text(match) or None
|
uuid_id = None
|
||||||
|
for attr in self.root.attrib:
|
||||||
|
if attr.endswith('unique-identifier'):
|
||||||
|
uuid_id = self.root.attrib[attr]
|
||||||
|
break
|
||||||
|
|
||||||
def fset(self, val):
|
matches = self.isbn_path(self.metadata)
|
||||||
uuid_id = None
|
if not val:
|
||||||
for attr in self.root.attrib:
|
for x in matches:
|
||||||
if attr.endswith('unique-identifier'):
|
xid = x.get('id', None)
|
||||||
uuid_id = self.root.attrib[attr]
|
is_package_identifier = uuid_id is not None and uuid_id == xid
|
||||||
break
|
if is_package_identifier:
|
||||||
|
self.set_text(x, str(uuid.uuid4()))
|
||||||
matches = self.isbn_path(self.metadata)
|
for attr in x.attrib:
|
||||||
if not val:
|
if attr.endswith('scheme'):
|
||||||
for x in matches:
|
x.attrib[attr] = 'uuid'
|
||||||
xid = x.get('id', None)
|
else:
|
||||||
is_package_identifier = uuid_id is not None and uuid_id == xid
|
x.getparent().remove(x)
|
||||||
if is_package_identifier:
|
return
|
||||||
self.set_text(x, str(uuid.uuid4()))
|
if not matches:
|
||||||
for attr in x.attrib:
|
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'}
|
||||||
if attr.endswith('scheme'):
|
matches = [self.create_metadata_element('identifier',
|
||||||
x.attrib[attr] = 'uuid'
|
attrib=attrib)]
|
||||||
else:
|
self.set_text(matches[0], unicode_type(val))
|
||||||
x.getparent().remove(x)
|
|
||||||
return
|
|
||||||
if not matches:
|
|
||||||
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'}
|
|
||||||
matches = [self.create_metadata_element('identifier',
|
|
||||||
attrib=attrib)]
|
|
||||||
self.set_text(matches[0], unicode_type(val))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def get_identifiers(self):
|
def get_identifiers(self):
|
||||||
identifiers = {}
|
identifiers = {}
|
||||||
@ -1024,85 +1006,73 @@ class OPF(object): # {{{
|
|||||||
self.set_text(self.create_metadata_element(
|
self.set_text(self.create_metadata_element(
|
||||||
'identifier', attrib=attrib), unicode_type(val))
|
'identifier', attrib=attrib), unicode_type(val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def application_id(self):
|
def application_id(self):
|
||||||
|
for match in self.application_id_path(self.metadata):
|
||||||
|
return self.get_text(match) or None
|
||||||
|
|
||||||
def fget(self):
|
@application_id.setter
|
||||||
for match in self.application_id_path(self.metadata):
|
def application_id(self, val):
|
||||||
return self.get_text(match) or None
|
removed_ids = set()
|
||||||
|
for x in tuple(self.application_id_path(self.metadata)):
|
||||||
|
removed_ids.add(x.get('id', None))
|
||||||
|
x.getparent().remove(x)
|
||||||
|
|
||||||
def fset(self, val):
|
uuid_id = None
|
||||||
removed_ids = set()
|
for attr in self.root.attrib:
|
||||||
for x in tuple(self.application_id_path(self.metadata)):
|
if attr.endswith('unique-identifier'):
|
||||||
removed_ids.add(x.get('id', None))
|
uuid_id = self.root.attrib[attr]
|
||||||
x.getparent().remove(x)
|
break
|
||||||
|
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'calibre'}
|
||||||
|
if uuid_id and uuid_id in removed_ids:
|
||||||
|
attrib['id'] = uuid_id
|
||||||
|
self.set_text(self.create_metadata_element(
|
||||||
|
'identifier', attrib=attrib), unicode_type(val))
|
||||||
|
|
||||||
uuid_id = None
|
@property
|
||||||
for attr in self.root.attrib:
|
|
||||||
if attr.endswith('unique-identifier'):
|
|
||||||
uuid_id = self.root.attrib[attr]
|
|
||||||
break
|
|
||||||
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'calibre'}
|
|
||||||
if uuid_id and uuid_id in removed_ids:
|
|
||||||
attrib['id'] = uuid_id
|
|
||||||
self.set_text(self.create_metadata_element(
|
|
||||||
'identifier', attrib=attrib), unicode_type(val))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def uuid(self):
|
def uuid(self):
|
||||||
|
for match in self.uuid_id_path(self.metadata):
|
||||||
|
return self.get_text(match) or None
|
||||||
|
|
||||||
def fget(self):
|
@uuid.setter
|
||||||
for match in self.uuid_id_path(self.metadata):
|
def uuid(self, val):
|
||||||
return self.get_text(match) or None
|
matches = self.uuid_id_path(self.metadata)
|
||||||
|
if not matches:
|
||||||
|
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'uuid'}
|
||||||
|
matches = [self.create_metadata_element('identifier',
|
||||||
|
attrib=attrib)]
|
||||||
|
self.set_text(matches[0], unicode_type(val))
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
matches = self.uuid_id_path(self.metadata)
|
|
||||||
if not matches:
|
|
||||||
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'uuid'}
|
|
||||||
matches = [self.create_metadata_element('identifier',
|
|
||||||
attrib=attrib)]
|
|
||||||
self.set_text(matches[0], unicode_type(val))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def language(self):
|
def language(self):
|
||||||
|
ans = self.languages
|
||||||
|
if ans:
|
||||||
|
return ans[0]
|
||||||
|
|
||||||
def fget(self):
|
@language.setter
|
||||||
ans = self.languages
|
def language(self, val):
|
||||||
if ans:
|
self.languages = [val]
|
||||||
return ans[0]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
self.languages = [val]
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def languages(self):
|
def languages(self):
|
||||||
|
ans = []
|
||||||
|
for match in self.languages_path(self.metadata):
|
||||||
|
t = self.get_text(match)
|
||||||
|
if t and t.strip():
|
||||||
|
l = canonicalize_lang(t.strip())
|
||||||
|
if l:
|
||||||
|
ans.append(l)
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@languages.setter
|
||||||
ans = []
|
def languages(self, val):
|
||||||
for match in self.languages_path(self.metadata):
|
matches = self.languages_path(self.metadata)
|
||||||
t = self.get_text(match)
|
for x in matches:
|
||||||
if t and t.strip():
|
x.getparent().remove(x)
|
||||||
l = canonicalize_lang(t.strip())
|
|
||||||
if l:
|
|
||||||
ans.append(l)
|
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, val):
|
for lang in val:
|
||||||
matches = self.languages_path(self.metadata)
|
l = self.create_metadata_element('language')
|
||||||
for x in matches:
|
self.set_text(l, unicode_type(lang))
|
||||||
x.getparent().remove(x)
|
|
||||||
|
|
||||||
for lang in val:
|
|
||||||
l = self.create_metadata_element('language')
|
|
||||||
self.set_text(l, unicode_type(lang))
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def raw_languages(self):
|
def raw_languages(self):
|
||||||
@ -1111,20 +1081,18 @@ class OPF(object): # {{{
|
|||||||
if t and t.strip():
|
if t and t.strip():
|
||||||
yield t.strip()
|
yield t.strip()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def book_producer(self):
|
def book_producer(self):
|
||||||
|
for match in self.bkp_path(self.metadata):
|
||||||
|
return self.get_text(match) or None
|
||||||
|
|
||||||
def fget(self):
|
@book_producer.setter
|
||||||
for match in self.bkp_path(self.metadata):
|
def book_producer(self, val):
|
||||||
return self.get_text(match) or None
|
matches = self.bkp_path(self.metadata)
|
||||||
|
if not matches:
|
||||||
def fset(self, val):
|
matches = [self.create_metadata_element('contributor')]
|
||||||
matches = self.bkp_path(self.metadata)
|
matches[0].set('{%s}role'%self.NAMESPACES['opf'], 'bkp')
|
||||||
if not matches:
|
self.set_text(matches[0], unicode_type(val))
|
||||||
matches = [self.create_metadata_element('contributor')]
|
|
||||||
matches[0].set('{%s}role'%self.NAMESPACES['opf'], 'bkp')
|
|
||||||
self.set_text(matches[0], unicode_type(val))
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def identifier_iter(self):
|
def identifier_iter(self):
|
||||||
for item in self.identifier_path(self.metadata):
|
for item in self.identifier_path(self.metadata):
|
||||||
@ -1238,42 +1206,39 @@ class OPF(object): # {{{
|
|||||||
if path and os.path.exists(path):
|
if path and os.path.exists(path):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def cover(self):
|
def cover(self):
|
||||||
|
if self.guide is not None:
|
||||||
|
for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'):
|
||||||
|
for item in self.guide:
|
||||||
|
if item.type and item.type.lower() == t:
|
||||||
|
return item.path
|
||||||
|
try:
|
||||||
|
if self.try_to_guess_cover:
|
||||||
|
return self.guess_cover()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def fget(self):
|
@cover.setter
|
||||||
if self.guide is not None:
|
def cover(self, path):
|
||||||
for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'):
|
if self.guide is not None:
|
||||||
for item in self.guide:
|
self.guide.set_cover(path)
|
||||||
if item.type and item.type.lower() == t:
|
for item in list(self.iterguide()):
|
||||||
return item.path
|
if 'cover' in item.get('type', ''):
|
||||||
try:
|
item.getparent().remove(item)
|
||||||
if self.try_to_guess_cover:
|
|
||||||
return self.guess_cover()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def fset(self, path):
|
else:
|
||||||
if self.guide is not None:
|
g = self.create_guide_element()
|
||||||
self.guide.set_cover(path)
|
self.guide = Guide()
|
||||||
for item in list(self.iterguide()):
|
self.guide.set_cover(path)
|
||||||
if 'cover' in item.get('type', ''):
|
etree.SubElement(g, 'opf:reference', nsmap=self.NAMESPACES,
|
||||||
item.getparent().remove(item)
|
attrib={'type':'cover', 'href':self.guide[-1].href()})
|
||||||
|
id = self.manifest.id_for_path(self.cover)
|
||||||
else:
|
if id is None:
|
||||||
g = self.create_guide_element()
|
for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'):
|
||||||
self.guide = Guide()
|
for item in self.guide:
|
||||||
self.guide.set_cover(path)
|
if item.type.lower() == t:
|
||||||
etree.SubElement(g, 'opf:reference', nsmap=self.NAMESPACES,
|
self.create_manifest_item(item.href(), guess_type(path)[0])
|
||||||
attrib={'type':'cover', 'href':self.guide[-1].href()})
|
|
||||||
id = self.manifest.id_for_path(self.cover)
|
|
||||||
if id is None:
|
|
||||||
for t in ('cover', 'other.ms-coverimage-standard', 'other.ms-coverimage'):
|
|
||||||
for item in self.guide:
|
|
||||||
if item.type.lower() == t:
|
|
||||||
self.create_manifest_item(item.href(), guess_type(path)[0])
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def get_metadata_element(self, name):
|
def get_metadata_element(self, name):
|
||||||
matches = self.metadata_elem_path(self.metadata, name=name)
|
matches = self.metadata_elem_path(self.metadata, name=name)
|
||||||
|
@ -122,19 +122,16 @@ class TOC(list):
|
|||||||
for i in obj.flat():
|
for i in obj.flat():
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def abspath(self):
|
def abspath(self):
|
||||||
doc='Return the file this toc entry points to as a absolute path to a file on the system.'
|
'Return the file this toc entry points to as a absolute path to a file on the system.'
|
||||||
|
|
||||||
def fget(self):
|
if self.href is None:
|
||||||
if self.href is None:
|
return None
|
||||||
return None
|
path = self.href.replace('/', os.sep)
|
||||||
path = self.href.replace('/', os.sep)
|
if not os.path.isabs(path):
|
||||||
if not os.path.isabs(path):
|
path = os.path.join(self.base_path, path)
|
||||||
path = os.path.join(self.base_path, path)
|
return path
|
||||||
return path
|
|
||||||
|
|
||||||
return property(fget=fget, doc=doc)
|
|
||||||
|
|
||||||
def read_from_opf(self, opfreader):
|
def read_from_opf(self, opfreader):
|
||||||
toc = opfreader.soup.find('spine', toc=True)
|
toc = opfreader.soup.find('spine', toc=True)
|
||||||
|
@ -131,14 +131,13 @@ class IndexEntry(object):
|
|||||||
' parent_index=%r)')%(self.offset, self.depth, self.length,
|
' parent_index=%r)')%(self.offset, self.depth, self.length,
|
||||||
self.index, self.parent_index)
|
self.index, self.parent_index)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
def fget(self):
|
return self.length
|
||||||
return self.length
|
|
||||||
|
|
||||||
def fset(self, val):
|
@size.setter
|
||||||
self.length = val
|
def size(self, val):
|
||||||
return property(fget=fget, fset=fset, doc='Alias for length')
|
self.length = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def next_offset(self):
|
def next_offset(self):
|
||||||
|
@ -704,20 +704,17 @@ class Metadata(object):
|
|||||||
if attr != nsattr:
|
if attr != nsattr:
|
||||||
attrib[nsattr] = attrib.pop(attr)
|
attrib[nsattr] = attrib.pop(attr)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
def fget(self):
|
return self.term
|
||||||
return self.term
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def content(self):
|
def content(self):
|
||||||
def fget(self):
|
return self.value
|
||||||
return self.value
|
|
||||||
|
|
||||||
def fset(self, value):
|
@content.setter
|
||||||
self.value = value
|
def content(self, value):
|
||||||
return property(fget=fget, fset=fset)
|
self.value = value
|
||||||
|
|
||||||
scheme = Attribute(lambda term: 'scheme' if
|
scheme = Attribute(lambda term: 'scheme' if
|
||||||
term == OPF('meta') else OPF('scheme'),
|
term == OPF('meta') else OPF('scheme'),
|
||||||
@ -830,33 +827,27 @@ class Metadata(object):
|
|||||||
def __getattr__(self, term):
|
def __getattr__(self, term):
|
||||||
return self.items[term]
|
return self.items[term]
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def _nsmap(self):
|
def _nsmap(self):
|
||||||
def fget(self):
|
nsmap = {}
|
||||||
nsmap = {}
|
for term in self.items:
|
||||||
for term in self.items:
|
for item in self.items[term]:
|
||||||
for item in self.items[term]:
|
nsmap.update(item.nsmap)
|
||||||
nsmap.update(item.nsmap)
|
return nsmap
|
||||||
return nsmap
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def _opf1_nsmap(self):
|
def _opf1_nsmap(self):
|
||||||
def fget(self):
|
nsmap = self._nsmap
|
||||||
nsmap = self._nsmap
|
for key, value in nsmap.items():
|
||||||
for key, value in nsmap.items():
|
if value in OPF_NSES or value in DC_NSES:
|
||||||
if value in OPF_NSES or value in DC_NSES:
|
del nsmap[key]
|
||||||
del nsmap[key]
|
return nsmap
|
||||||
return nsmap
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def _opf2_nsmap(self):
|
def _opf2_nsmap(self):
|
||||||
def fget(self):
|
nsmap = self._nsmap
|
||||||
nsmap = self._nsmap
|
nsmap.update(OPF2_NSMAP)
|
||||||
nsmap.update(OPF2_NSMAP)
|
return nsmap
|
||||||
return nsmap
|
|
||||||
return property(fget=fget)
|
|
||||||
|
|
||||||
def to_opf1(self, parent=None):
|
def to_opf1(self, parent=None):
|
||||||
nsmap = self._opf1_nsmap
|
nsmap = self._opf1_nsmap
|
||||||
@ -1011,9 +1002,9 @@ class Manifest(object):
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
doc = """Provides MIME type sensitive access to the manifest
|
"""Provides MIME type sensitive access to the manifest
|
||||||
entry's associated content.
|
entry's associated content.
|
||||||
|
|
||||||
- XHTML, HTML, and variant content is parsed as necessary to
|
- XHTML, HTML, and variant content is parsed as necessary to
|
||||||
@ -1025,40 +1016,39 @@ class Manifest(object):
|
|||||||
- All other content is returned as a :class:`str` object with no
|
- All other content is returned as a :class:`str` object with no
|
||||||
special parsing.
|
special parsing.
|
||||||
"""
|
"""
|
||||||
|
data = self._data
|
||||||
|
if data is None:
|
||||||
|
if self._loader is None:
|
||||||
|
return None
|
||||||
|
data = self._loader(getattr(self, 'html_input_href',
|
||||||
|
self.href))
|
||||||
|
try:
|
||||||
|
mt = self.media_type.lower()
|
||||||
|
except Exception:
|
||||||
|
mt = 'application/octet-stream'
|
||||||
|
if not isinstance(data, string_or_bytes):
|
||||||
|
pass # already parsed
|
||||||
|
elif mt in OEB_DOCS:
|
||||||
|
data = self._parse_xhtml(data)
|
||||||
|
elif mt[-4:] in ('+xml', '/xml'):
|
||||||
|
data = self._parse_xml(data)
|
||||||
|
elif mt in OEB_STYLES:
|
||||||
|
data = self._parse_css(data)
|
||||||
|
elif mt == 'text/plain':
|
||||||
|
self.oeb.log.warn('%s contains data in TXT format'%self.href,
|
||||||
|
'converting to HTML')
|
||||||
|
data = self._parse_txt(data)
|
||||||
|
self.media_type = XHTML_MIME
|
||||||
|
self._data = data
|
||||||
|
return data
|
||||||
|
|
||||||
def fget(self):
|
@data.setter
|
||||||
data = self._data
|
def data(self, value):
|
||||||
if data is None:
|
self._data = value
|
||||||
if self._loader is None:
|
|
||||||
return None
|
|
||||||
data = self._loader(getattr(self, 'html_input_href',
|
|
||||||
self.href))
|
|
||||||
try:
|
|
||||||
mt = self.media_type.lower()
|
|
||||||
except Exception:
|
|
||||||
mt = 'application/octet-stream'
|
|
||||||
if not isinstance(data, string_or_bytes):
|
|
||||||
pass # already parsed
|
|
||||||
elif mt in OEB_DOCS:
|
|
||||||
data = self._parse_xhtml(data)
|
|
||||||
elif mt[-4:] in ('+xml', '/xml'):
|
|
||||||
data = self._parse_xml(data)
|
|
||||||
elif mt in OEB_STYLES:
|
|
||||||
data = self._parse_css(data)
|
|
||||||
elif mt == 'text/plain':
|
|
||||||
self.oeb.log.warn('%s contains data in TXT format'%self.href,
|
|
||||||
'converting to HTML')
|
|
||||||
data = self._parse_txt(data)
|
|
||||||
self.media_type = XHTML_MIME
|
|
||||||
self._data = data
|
|
||||||
return data
|
|
||||||
|
|
||||||
def fset(self, value):
|
@data.deleter
|
||||||
self._data = value
|
def data(self):
|
||||||
|
self._data = None
|
||||||
def fdel(self):
|
|
||||||
self._data = None
|
|
||||||
return property(fget, fset, fdel, doc=doc)
|
|
||||||
|
|
||||||
def unload_data_from_memory(self, memory=None):
|
def unload_data_from_memory(self, memory=None):
|
||||||
if isinstance(self._data, bytes):
|
if isinstance(self._data, bytes):
|
||||||
@ -1266,20 +1256,19 @@ class Manifest(object):
|
|||||||
element(elem, OPF('item'), attrib=attrib)
|
element(elem, OPF('item'), attrib=attrib)
|
||||||
return elem
|
return elem
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def main_stylesheet(self):
|
def main_stylesheet(self):
|
||||||
def fget(self):
|
ans = getattr(self, '_main_stylesheet', None)
|
||||||
ans = getattr(self, '_main_stylesheet', None)
|
if ans is None:
|
||||||
if ans is None:
|
for item in self:
|
||||||
for item in self:
|
if item.media_type.lower() in OEB_STYLES:
|
||||||
if item.media_type.lower() in OEB_STYLES:
|
ans = item
|
||||||
ans = item
|
break
|
||||||
break
|
return ans
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, item):
|
@main_stylesheet.setter
|
||||||
self._main_stylesheet = item
|
def main_stylesheet(self, item):
|
||||||
return property(fget=fget, fset=fset)
|
self._main_stylesheet = item
|
||||||
|
|
||||||
|
|
||||||
class Spine(object):
|
class Spine(object):
|
||||||
@ -1422,15 +1411,12 @@ class Guide(object):
|
|||||||
return 'Reference(type=%r, title=%r, href=%r)' \
|
return 'Reference(type=%r, title=%r, href=%r)' \
|
||||||
% (self.type, self.title, self.href)
|
% (self.type, self.title, self.href)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def item(self):
|
def item(self):
|
||||||
doc = """The manifest item associated with this reference."""
|
"""The manifest item associated with this reference."""
|
||||||
|
path = urldefrag(self.href)[0]
|
||||||
def fget(self):
|
hrefs = self.oeb.manifest.hrefs
|
||||||
path = urldefrag(self.href)[0]
|
return hrefs.get(path, None)
|
||||||
hrefs = self.oeb.manifest.hrefs
|
|
||||||
return hrefs.get(path, None)
|
|
||||||
return property(fget=fget, doc=doc)
|
|
||||||
|
|
||||||
def __init__(self, oeb):
|
def __init__(self, oeb):
|
||||||
self.oeb = oeb
|
self.oeb = oeb
|
||||||
|
@ -1369,14 +1369,13 @@ class EpubContainer(Container):
|
|||||||
with self.open(name, 'wb') as f:
|
with self.open(name, 'wb') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def path_to_ebook(self):
|
def path_to_ebook(self):
|
||||||
def fget(self):
|
return self.pathtoepub
|
||||||
return self.pathtoepub
|
|
||||||
|
|
||||||
def fset(self, val):
|
@path_to_ebook.setter
|
||||||
self.pathtoepub = val
|
def path_to_ebook(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.pathtoepub = val
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -1496,14 +1495,13 @@ class AZW3Container(Container):
|
|||||||
outpath = self.pathtoazw3
|
outpath = self.pathtoazw3
|
||||||
opf_to_azw3(self.name_path_map[self.opf_name], outpath, self)
|
opf_to_azw3(self.name_path_map[self.opf_name], outpath, self)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def path_to_ebook(self):
|
def path_to_ebook(self):
|
||||||
def fget(self):
|
return self.pathtoazw3
|
||||||
return self.pathtoazw3
|
|
||||||
|
|
||||||
def fset(self, val):
|
@path_to_ebook.setter
|
||||||
self.pathtoazw3 = val
|
def path_to_ebook(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.pathtoazw3 = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def names_that_must_not_be_changed(self):
|
def names_that_must_not_be_changed(self):
|
||||||
|
@ -1022,19 +1022,19 @@ class Application(QApplication):
|
|||||||
else:
|
else:
|
||||||
return QApplication.event(self, e)
|
return QApplication.event(self, e)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_custom_colors(self):
|
def current_custom_colors(self):
|
||||||
from PyQt5.Qt import QColorDialog, QColor
|
from PyQt5.Qt import QColorDialog
|
||||||
|
|
||||||
def fget(self):
|
return [col.getRgb() for col in
|
||||||
return [col.getRgb() for col in
|
|
||||||
(QColorDialog.customColor(i) for i in range(QColorDialog.customCount()))]
|
(QColorDialog.customColor(i) for i in range(QColorDialog.customCount()))]
|
||||||
|
|
||||||
def fset(self, colors):
|
@current_custom_colors.setter
|
||||||
num = min(len(colors), QColorDialog.customCount())
|
def current_custom_colors(self, colors):
|
||||||
for i in range(num):
|
from PyQt5.Qt import QColorDialog, QColor
|
||||||
QColorDialog.setCustomColor(i, QColor(*colors[i]))
|
num = min(len(colors), QColorDialog.customCount())
|
||||||
return property(fget=fget, fset=fset)
|
for i in range(num):
|
||||||
|
QColorDialog.setCustomColor(i, QColor(*colors[i]))
|
||||||
|
|
||||||
def read_custom_colors(self):
|
def read_custom_colors(self):
|
||||||
colors = self.color_prefs.get('custom_colors_for_color_dialog', None)
|
colors = self.color_prefs.get('custom_colors_for_color_dialog', None)
|
||||||
|
@ -51,18 +51,17 @@ class ChooseFormat(QDialog): # {{{
|
|||||||
b.setChecked(True)
|
b.setChecked(True)
|
||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def formats(self):
|
def formats(self):
|
||||||
def fget(self):
|
for b in self.buttons:
|
||||||
for b in self.buttons:
|
if b.isChecked():
|
||||||
if b.isChecked():
|
yield unicode_type(b.text())[1:]
|
||||||
yield unicode_type(b.text())[1:]
|
|
||||||
|
|
||||||
def fset(self, formats):
|
@formats.setter
|
||||||
formats = {x.upper() for x in formats}
|
def formats(self, formats):
|
||||||
for b in self.buttons:
|
formats = {x.upper() for x in formats}
|
||||||
b.setChecked(b.text()[1:] in formats)
|
for b in self.buttons:
|
||||||
return property(fget=fget, fset=fset)
|
b.setChecked(b.text()[1:] in formats)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -336,55 +336,53 @@ class EditorWidget(QWebView, LineEditECM): # {{{
|
|||||||
def remove_format_cleanup(self):
|
def remove_format_cleanup(self):
|
||||||
self.html = self.html
|
self.html = self.html
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def html(self):
|
def html(self):
|
||||||
|
ans = u''
|
||||||
|
try:
|
||||||
|
if not self.page().mainFrame().documentElement().findFirst('meta[name="calibre-dont-sanitize"]').isNull():
|
||||||
|
# Bypass cleanup if special meta tag exists
|
||||||
|
return unicode_type(self.page().mainFrame().toHtml())
|
||||||
|
check = unicode_type(self.page().mainFrame().toPlainText()).strip()
|
||||||
|
raw = unicode_type(self.page().mainFrame().toHtml())
|
||||||
|
raw = xml_to_unicode(raw, strip_encoding_pats=True,
|
||||||
|
resolve_entities=True)[0]
|
||||||
|
raw = self.comments_pat.sub('', raw)
|
||||||
|
if not check and '<img' not in raw.lower():
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
|
||||||
ans = u''
|
|
||||||
try:
|
try:
|
||||||
if not self.page().mainFrame().documentElement().findFirst('meta[name="calibre-dont-sanitize"]').isNull():
|
root = html.fromstring(raw)
|
||||||
# Bypass cleanup if special meta tag exists
|
except Exception:
|
||||||
return unicode_type(self.page().mainFrame().toHtml())
|
root = parse(raw, maybe_xhtml=False, sanitize_names=True)
|
||||||
check = unicode_type(self.page().mainFrame().toPlainText()).strip()
|
|
||||||
raw = unicode_type(self.page().mainFrame().toHtml())
|
|
||||||
raw = xml_to_unicode(raw, strip_encoding_pats=True,
|
|
||||||
resolve_entities=True)[0]
|
|
||||||
raw = self.comments_pat.sub('', raw)
|
|
||||||
if not check and '<img' not in raw.lower():
|
|
||||||
return ans
|
|
||||||
|
|
||||||
try:
|
elems = []
|
||||||
root = html.fromstring(raw)
|
for body in root.xpath('//body'):
|
||||||
except Exception:
|
if body.text:
|
||||||
root = parse(raw, maybe_xhtml=False, sanitize_names=True)
|
elems.append(body.text)
|
||||||
|
elems += [html.tostring(x, encoding=unicode_type) for x in body if
|
||||||
|
x.tag not in ('script', 'style')]
|
||||||
|
|
||||||
elems = []
|
if len(elems) > 1:
|
||||||
for body in root.xpath('//body'):
|
ans = u'<div>%s</div>'%(u''.join(elems))
|
||||||
if body.text:
|
|
||||||
elems.append(body.text)
|
|
||||||
elems += [html.tostring(x, encoding=unicode_type) for x in body if
|
|
||||||
x.tag not in ('script', 'style')]
|
|
||||||
|
|
||||||
if len(elems) > 1:
|
|
||||||
ans = u'<div>%s</div>'%(u''.join(elems))
|
|
||||||
else:
|
|
||||||
ans = u''.join(elems)
|
|
||||||
if not ans.startswith('<'):
|
|
||||||
ans = '<p>%s</p>'%ans
|
|
||||||
ans = xml_replace_entities(ans)
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, val):
|
|
||||||
if self.base_url is None:
|
|
||||||
self.setHtml(val)
|
|
||||||
else:
|
else:
|
||||||
self.setHtml(val, self.base_url)
|
ans = u''.join(elems)
|
||||||
self.set_font_style()
|
if not ans.startswith('<'):
|
||||||
return property(fget=fget, fset=fset)
|
ans = '<p>%s</p>'%ans
|
||||||
|
ans = xml_replace_entities(ans)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
return ans
|
||||||
|
|
||||||
|
@html.setter
|
||||||
|
def html(self, val):
|
||||||
|
if self.base_url is None:
|
||||||
|
self.setHtml(val)
|
||||||
|
else:
|
||||||
|
self.setHtml(val, self.base_url)
|
||||||
|
self.set_font_style()
|
||||||
|
|
||||||
def set_base_url(self, qurl):
|
def set_base_url(self, qurl):
|
||||||
self.base_url = qurl
|
self.base_url = qurl
|
||||||
@ -763,15 +761,14 @@ class Editor(QWidget): # {{{
|
|||||||
def set_minimum_height_for_editor(self, val):
|
def set_minimum_height_for_editor(self, val):
|
||||||
self.editor.setMinimumHeight(val)
|
self.editor.setMinimumHeight(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def html(self):
|
def html(self):
|
||||||
def fset(self, v):
|
self.tabs.setCurrentIndex(0)
|
||||||
self.editor.html = v
|
return self.editor.html
|
||||||
|
|
||||||
def fget(self):
|
@html.setter
|
||||||
self.tabs.setCurrentIndex(0)
|
def html(self, v):
|
||||||
return self.editor.html
|
self.editor.html = v
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def change_tab(self, index):
|
def change_tab(self, index):
|
||||||
# print 'reloading:', (index and self.wyswyg_dirty) or (not index and
|
# print 'reloading:', (index and self.wyswyg_dirty) or (not index and
|
||||||
@ -785,14 +782,13 @@ class Editor(QWidget): # {{{
|
|||||||
self.editor.html = unicode_type(self.code_edit.toPlainText())
|
self.editor.html = unicode_type(self.code_edit.toPlainText())
|
||||||
self.source_dirty = False
|
self.source_dirty = False
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def tab(self):
|
def tab(self):
|
||||||
def fget(self):
|
return 'code' if self.tabs.currentWidget() is self.code_edit else 'wyswyg'
|
||||||
return 'code' if self.tabs.currentWidget() is self.code_edit else 'wyswyg'
|
|
||||||
|
|
||||||
def fset(self, val):
|
@tab.setter
|
||||||
self.tabs.setCurrentWidget(self.code_edit if val == 'code' else self.wyswyg)
|
def tab(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.tabs.setCurrentWidget(self.code_edit if val == 'code' else self.wyswyg)
|
||||||
|
|
||||||
def wyswyg_dirtied(self, *args):
|
def wyswyg_dirtied(self, *args):
|
||||||
self.wyswyg_dirty = True
|
self.wyswyg_dirty = True
|
||||||
@ -816,14 +812,13 @@ class Editor(QWidget): # {{{
|
|||||||
if self.toolbar_prefs_name is not None:
|
if self.toolbar_prefs_name is not None:
|
||||||
gprefs.set(self.toolbar_prefs_name, visible)
|
gprefs.set(self.toolbar_prefs_name, visible)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def toolbars_visible(self):
|
def toolbars_visible(self):
|
||||||
def fget(self):
|
return self.toolbar1.isVisible() or self.toolbar2.isVisible() or self.toolbar3.isVisible()
|
||||||
return self.toolbar1.isVisible() or self.toolbar2.isVisible() or self.toolbar3.isVisible()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@toolbars_visible.setter
|
||||||
getattr(self, ('show' if val else 'hide') + '_toolbars')()
|
def toolbars_visible(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
getattr(self, ('show' if val else 'hide') + '_toolbars')()
|
||||||
|
|
||||||
def set_readonly(self, what):
|
def set_readonly(self, what):
|
||||||
self.editor.set_readonly(what)
|
self.editor.set_readonly(what)
|
||||||
|
@ -333,23 +333,21 @@ class LineEdit(QLineEdit, LineEditECM):
|
|||||||
def set_add_separator(self, what):
|
def set_add_separator(self, what):
|
||||||
self.add_separator = bool(what)
|
self.add_separator = bool(what)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def all_items(self):
|
def all_items(self):
|
||||||
def fget(self):
|
return self.mcompleter.model().all_items
|
||||||
return self.mcompleter.model().all_items
|
|
||||||
|
|
||||||
def fset(self, items):
|
@all_items.setter
|
||||||
self.mcompleter.model().set_items(items)
|
def all_items(self, items):
|
||||||
return property(fget=fget, fset=fset)
|
self.mcompleter.model().set_items(items)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def disable_popup(self):
|
def disable_popup(self):
|
||||||
def fget(self):
|
return self.mcompleter.disable_popup
|
||||||
return self.mcompleter.disable_popup
|
|
||||||
|
|
||||||
def fset(self, val):
|
@disable_popup.setter
|
||||||
self.mcompleter.disable_popup = bool(val)
|
def disable_popup(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.mcompleter.disable_popup = bool(val)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
def event(self, ev):
|
def event(self, ev):
|
||||||
@ -471,23 +469,21 @@ class EditWithComplete(EnComboBox):
|
|||||||
self.setText(what)
|
self.setText(what)
|
||||||
self.lineEdit().selectAll()
|
self.lineEdit().selectAll()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def all_items(self):
|
def all_items(self):
|
||||||
def fget(self):
|
return self.lineEdit().all_items
|
||||||
return self.lineEdit().all_items
|
|
||||||
|
|
||||||
def fset(self, val):
|
@all_items.setter
|
||||||
self.lineEdit().all_items = val
|
def all_items(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.lineEdit().all_items = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def disable_popup(self):
|
def disable_popup(self):
|
||||||
def fget(self):
|
return self.lineEdit().disable_popup
|
||||||
return self.lineEdit().disable_popup
|
|
||||||
|
|
||||||
def fset(self, val):
|
@disable_popup.setter
|
||||||
self.lineEdit().disable_popup = bool(val)
|
def disable_popup(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.lineEdit().disable_popup = bool(val)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
def text(self):
|
def text(self):
|
||||||
|
@ -43,14 +43,13 @@ class ColorButton(QToolButton):
|
|||||||
self.setIcon(QIcon(self.pix))
|
self.setIcon(QIcon(self.pix))
|
||||||
self.clicked.connect(self.choose_color)
|
self.clicked.connect(self.choose_color)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def color(self):
|
def color(self):
|
||||||
def fget(self):
|
return self._color.name(QColor.HexRgb)[1:]
|
||||||
return self._color.name(QColor.HexRgb)[1:]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@color.setter
|
||||||
self._color = QColor('#' + val)
|
def color(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._color = QColor('#' + val)
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
self.pix.fill(self._color)
|
self.pix.fill(self._color)
|
||||||
|
@ -377,14 +377,13 @@ class Comments(Base):
|
|||||||
val = None
|
val = None
|
||||||
return val
|
return val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def tab(self):
|
def tab(self):
|
||||||
def fget(self):
|
return self._tb.tab
|
||||||
return self._tb.tab
|
|
||||||
|
|
||||||
def fset(self, val):
|
@tab.setter
|
||||||
self._tb.tab = val
|
def tab(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._tb.tab = val
|
||||||
|
|
||||||
def connect_data_changed(self, slot):
|
def connect_data_changed(self, slot):
|
||||||
self._tb.data_changed.connect(slot)
|
self._tb.data_changed.connect(slot)
|
||||||
|
@ -1367,29 +1367,26 @@ class DeviceMixin(object): # {{{
|
|||||||
memory=[files, remove])
|
memory=[files, remove])
|
||||||
self.status_bar.show_message(_('Sending catalogs to device.'), 5000)
|
self.status_bar.show_message(_('Sending catalogs to device.'), 5000)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def news_to_be_synced(self):
|
def news_to_be_synced(self):
|
||||||
doc = 'Set of ids to be sent to device'
|
'Set of ids to be sent to device'
|
||||||
|
ans = []
|
||||||
|
try:
|
||||||
|
ans = self.library_view.model().db.prefs.get('news_to_be_synced',
|
||||||
|
[])
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return set(ans)
|
||||||
|
|
||||||
def fget(self):
|
@news_to_be_synced.setter
|
||||||
ans = []
|
def news_to_be_synced(self, ids):
|
||||||
try:
|
try:
|
||||||
ans = self.library_view.model().db.prefs.get('news_to_be_synced',
|
self.library_view.model().db.new_api.set_pref('news_to_be_synced',
|
||||||
[])
|
list(ids))
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return set(ans)
|
|
||||||
|
|
||||||
def fset(self, ids):
|
|
||||||
try:
|
|
||||||
self.library_view.model().db.new_api.set_pref('news_to_be_synced',
|
|
||||||
list(ids))
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset, doc=doc)
|
|
||||||
|
|
||||||
def sync_news(self, send_ids=None, do_auto_convert=True):
|
def sync_news(self, send_ids=None, do_auto_convert=True):
|
||||||
if self.device_connected:
|
if self.device_connected:
|
||||||
|
@ -378,32 +378,31 @@ class BasicRecipe(QWidget): # {{{
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def recipe_source(self):
|
def recipe_source(self):
|
||||||
|
|
||||||
def fget(self):
|
title = self.title.text().strip()
|
||||||
title = self.title.text().strip()
|
feeds = [self.feeds.item(i).data(Qt.UserRole) for i in range(self.feeds.count())]
|
||||||
feeds = [self.feeds.item(i).data(Qt.UserRole) for i in range(self.feeds.count())]
|
return options_to_recipe_source(title, self.oldest_article.value(), self.max_articles.value(), feeds)
|
||||||
return options_to_recipe_source(title, self.oldest_article.value(), self.max_articles.value(), feeds)
|
|
||||||
|
|
||||||
def fset(self, src):
|
@recipe_source.setter
|
||||||
self.feeds.clear()
|
def recipe_source(self, src):
|
||||||
self.feed_title.clear()
|
self.feeds.clear()
|
||||||
self.feed_url.clear()
|
self.feed_title.clear()
|
||||||
if src is None:
|
self.feed_url.clear()
|
||||||
self.title.setText(_('My news source'))
|
if src is None:
|
||||||
self.oldest_article.setValue(7)
|
self.title.setText(_('My news source'))
|
||||||
self.max_articles.setValue(100)
|
self.oldest_article.setValue(7)
|
||||||
else:
|
self.max_articles.setValue(100)
|
||||||
recipe = compile_recipe(src)
|
else:
|
||||||
self.title.setText(recipe.title)
|
recipe = compile_recipe(src)
|
||||||
self.oldest_article.setValue(recipe.oldest_article)
|
self.title.setText(recipe.title)
|
||||||
self.max_articles.setValue(recipe.max_articles_per_feed)
|
self.oldest_article.setValue(recipe.oldest_article)
|
||||||
for x in (recipe.feeds or ()):
|
self.max_articles.setValue(recipe.max_articles_per_feed)
|
||||||
title, url = ('', x) if len(x) == 1 else x
|
for x in (recipe.feeds or ()):
|
||||||
QListWidgetItem('%s - %s' % (title, url), self.feeds).setData(Qt.UserRole, (title, url))
|
title, url = ('', x) if len(x) == 1 else x
|
||||||
|
QListWidgetItem('%s - %s' % (title, url), self.feeds).setData(Qt.UserRole, (title, url))
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
@ -431,16 +430,13 @@ class AdvancedRecipe(QWidget): # {{{
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def recipe_source(self):
|
def recipe_source(self):
|
||||||
|
return self.editor.toPlainText()
|
||||||
|
|
||||||
def fget(self):
|
@recipe_source.setter
|
||||||
return self.editor.toPlainText()
|
def recipe_source(self, src):
|
||||||
|
self.editor.load_text(src, syntax='python', doc_name='<recipe>')
|
||||||
def fset(self, src):
|
|
||||||
self.editor.load_text(src, syntax='python', doc_name='<recipe>')
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(800, 500)
|
return QSize(800, 500)
|
||||||
|
@ -64,14 +64,13 @@ class ProgressDialog(QDialog):
|
|||||||
def set_value(self, val):
|
def set_value(self, val):
|
||||||
self.value = val
|
self.value = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
def fset(self, val):
|
return self.bar.value()
|
||||||
return self.bar.setValue(val)
|
|
||||||
|
|
||||||
def fget(self):
|
@value.setter
|
||||||
return self.bar.value()
|
def value(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.bar.setValue(val)
|
||||||
|
|
||||||
def set_min(self, min):
|
def set_min(self, min):
|
||||||
self.min = min
|
self.min = min
|
||||||
@ -79,42 +78,38 @@ class ProgressDialog(QDialog):
|
|||||||
def set_max(self, max):
|
def set_max(self, max):
|
||||||
self.max = max
|
self.max = max
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def max(self):
|
def max(self):
|
||||||
def fget(self):
|
return self.bar.maximum()
|
||||||
return self.bar.maximum()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@max.setter
|
||||||
self.bar.setMaximum(val)
|
def max(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.bar.setMaximum(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def min(self):
|
def min(self):
|
||||||
def fget(self):
|
return self.bar.minimum()
|
||||||
return self.bar.minimum()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@min.setter
|
||||||
self.bar.setMinimum(val)
|
def min(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.bar.setMinimum(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def title(self):
|
def title(self):
|
||||||
def fget(self):
|
return self.title_label.text()
|
||||||
return self.title_label.text()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@title.setter
|
||||||
self.title_label.setText(unicode_type(val or ''))
|
def title(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.title_label.setText(unicode_type(val or ''))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def msg(self):
|
def msg(self):
|
||||||
def fget(self):
|
return self.message.text()
|
||||||
return self.message.text()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@msg.setter
|
||||||
val = unicode_type(val or '')
|
def msg(self, val):
|
||||||
self.message.setText(elided_text(val, self.font(), self.message.minimumWidth()-10))
|
val = unicode_type(val or '')
|
||||||
return property(fget=fget, fset=fset)
|
self.message.setText(elided_text(val, self.font(), self.message.minimumWidth()-10))
|
||||||
|
|
||||||
def _canceled(self, *args):
|
def _canceled(self, *args):
|
||||||
self.canceled = True
|
self.canceled = True
|
||||||
|
@ -353,18 +353,17 @@ class FontFamilyChooser(QWidget):
|
|||||||
def clear_family(self):
|
def clear_family(self):
|
||||||
self.font_family = None
|
self.font_family = None
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def font_family(self):
|
def font_family(self):
|
||||||
def fget(self):
|
return self._current_family
|
||||||
return self._current_family
|
|
||||||
|
|
||||||
def fset(self, val):
|
@font_family.setter
|
||||||
if not val:
|
def font_family(self, val):
|
||||||
val = None
|
if not val:
|
||||||
self._current_family = val
|
val = None
|
||||||
self.button.setText(val or self.default_text)
|
self._current_family = val
|
||||||
self.family_changed.emit(val)
|
self.button.setText(val or self.default_text)
|
||||||
return property(fget=fget, fset=fset)
|
self.family_changed.emit(val)
|
||||||
|
|
||||||
def show_chooser(self):
|
def show_chooser(self):
|
||||||
d = FontFamilyDialog(self.font_family, self)
|
d = FontFamilyDialog(self.font_family, self)
|
||||||
|
@ -60,23 +60,20 @@ class LanguagesEdit(EditWithComplete):
|
|||||||
parts = [x.strip() for x in raw.split(',')]
|
parts = [x.strip() for x in raw.split(',')]
|
||||||
return [self.comma_rmap.get(x, x) for x in parts]
|
return [self.comma_rmap.get(x, x) for x in parts]
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def lang_codes(self):
|
def lang_codes(self):
|
||||||
|
vals = self.vals
|
||||||
|
ans = []
|
||||||
|
for name in vals:
|
||||||
|
if name:
|
||||||
|
code = self._rmap.get(lower(name), None)
|
||||||
|
if code is not None:
|
||||||
|
ans.append(code)
|
||||||
|
return ans
|
||||||
|
|
||||||
def fget(self):
|
@lang_codes.setter
|
||||||
vals = self.vals
|
def lang_codes(self, lang_codes):
|
||||||
ans = []
|
self.set_lang_codes(lang_codes, allow_undo=False)
|
||||||
for name in vals:
|
|
||||||
if name:
|
|
||||||
code = self._rmap.get(lower(name), None)
|
|
||||||
if code is not None:
|
|
||||||
ans.append(code)
|
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, lang_codes):
|
|
||||||
self.set_lang_codes(lang_codes, allow_undo=False)
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def set_lang_codes(self, lang_codes, allow_undo=True):
|
def set_lang_codes(self, lang_codes, allow_undo=True):
|
||||||
ans = []
|
ans = []
|
||||||
|
@ -186,18 +186,17 @@ class PreserveViewState(object): # {{{
|
|||||||
view.horizontalScrollBar().setValue(self.hscroll)
|
view.horizontalScrollBar().setValue(self.hscroll)
|
||||||
self.init_vals()
|
self.init_vals()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
def fget(self):
|
self.__enter__()
|
||||||
self.__enter__()
|
return {x:getattr(self, x) for x in ('selected_ids', 'current_id',
|
||||||
return {x:getattr(self, x) for x in ('selected_ids', 'current_id',
|
'vscroll', 'hscroll')}
|
||||||
'vscroll', 'hscroll')}
|
|
||||||
|
|
||||||
def fset(self, state):
|
@state.setter
|
||||||
for k, v in iteritems(state):
|
def state(self, state):
|
||||||
setattr(self, k, v)
|
for k, v in iteritems(state):
|
||||||
self.__exit__()
|
setattr(self, k, v)
|
||||||
return property(fget=fget, fset=fset)
|
self.__exit__()
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -1161,24 +1160,23 @@ class BooksView(QTableView): # {{{
|
|||||||
ans.append(i)
|
ans.append(i)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_id(self):
|
def current_id(self):
|
||||||
def fget(self):
|
try:
|
||||||
try:
|
return self.model().id(self.currentIndex())
|
||||||
return self.model().id(self.currentIndex())
|
except:
|
||||||
except:
|
pass
|
||||||
pass
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_id.setter
|
||||||
if val is None:
|
def current_id(self, val):
|
||||||
return
|
if val is None:
|
||||||
m = self.model()
|
return
|
||||||
for row in range(m.rowCount(QModelIndex())):
|
m = self.model()
|
||||||
if m.id(row) == val:
|
for row in range(m.rowCount(QModelIndex())):
|
||||||
self.set_current_row(row, select=False)
|
if m.id(row) == val:
|
||||||
break
|
self.set_current_row(row, select=False)
|
||||||
return property(fget=fget, fset=fset)
|
break
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def next_id(self):
|
def next_id(self):
|
||||||
|
@ -72,14 +72,13 @@ class BasicMetadataWidget(object):
|
|||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
# Present in most but not all basic metadata widgets
|
return None
|
||||||
def fget(self):
|
|
||||||
return None
|
@current_val.setter
|
||||||
def fset(self, val):
|
def current_val(self, val):
|
||||||
pass
|
pass
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
@ -225,24 +224,22 @@ class TitleEdit(EnLineEdit, ToMetadataMixin):
|
|||||||
# to work even if some of the book files are opened in windows.
|
# to work even if some of the book files are opened in windows.
|
||||||
getattr(db, 'set_'+ self.TITLE_ATTR)(id_, title, notify=False)
|
getattr(db, 'set_'+ self.TITLE_ATTR)(id_, title, notify=False)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
title = clean_text(unicode_type(self.text()))
|
||||||
title = clean_text(unicode_type(self.text()))
|
if not title:
|
||||||
if not title:
|
title = self.get_default()
|
||||||
title = self.get_default()
|
return title.strip()
|
||||||
return title.strip()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if hasattr(val, 'strip'):
|
def current_val(self, val):
|
||||||
val = val.strip()
|
if hasattr(val, 'strip'):
|
||||||
if not val:
|
val = val.strip()
|
||||||
val = self.get_default()
|
if not val:
|
||||||
self.set_text(val)
|
val = self.get_default()
|
||||||
self.setCursorPosition(0)
|
self.set_text(val)
|
||||||
|
self.setCursorPosition(0)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def break_cycles(self):
|
def break_cycles(self):
|
||||||
self.dialog = None
|
self.dialog = None
|
||||||
@ -416,22 +413,20 @@ class AuthorsEdit(EditWithComplete, ToMetadataMixin):
|
|||||||
self.books_to_refresh |= db.set_authors(id_, authors, notify=False,
|
self.books_to_refresh |= db.set_authors(id_, authors, notify=False,
|
||||||
allow_case_change=True)
|
allow_case_change=True)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
au = clean_text(unicode_type(self.text()))
|
||||||
au = clean_text(unicode_type(self.text()))
|
if not au:
|
||||||
if not au:
|
au = self.get_default()
|
||||||
au = self.get_default()
|
return string_to_authors(au)
|
||||||
return string_to_authors(au)
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val:
|
def current_val(self, val):
|
||||||
val = [self.get_default()]
|
if not val:
|
||||||
self.set_edit_text(' & '.join([x.strip() for x in val]))
|
val = [self.get_default()]
|
||||||
self.lineEdit().setCursorPosition(0)
|
self.set_edit_text(' & '.join([x.strip() for x in val]))
|
||||||
|
self.lineEdit().setCursorPosition(0)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def break_cycles(self):
|
def break_cycles(self):
|
||||||
self.db = self.dialog = None
|
self.db = self.dialog = None
|
||||||
@ -485,19 +480,17 @@ class AuthorSortEdit(EnLineEdit, ToMetadataMixin):
|
|||||||
self.first_time = True
|
self.first_time = True
|
||||||
self.update_state()
|
self.update_state()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
return clean_text(unicode_type(self.text()))
|
||||||
return clean_text(unicode_type(self.text()))
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val:
|
def current_val(self, val):
|
||||||
val = ''
|
if not val:
|
||||||
self.set_text(val.strip())
|
val = ''
|
||||||
self.setCursorPosition(0)
|
self.set_text(val.strip())
|
||||||
|
self.setCursorPosition(0)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def update_state_and_val(self):
|
def update_state_and_val(self):
|
||||||
# Handle case change if the authors box changed
|
# Handle case change if the authors box changed
|
||||||
@ -613,19 +606,17 @@ class SeriesEdit(EditWithComplete, ToMetadataMixin):
|
|||||||
self.books_to_refresh = set([])
|
self.books_to_refresh = set([])
|
||||||
self.lineEdit().textChanged.connect(self.data_changed)
|
self.lineEdit().textChanged.connect(self.data_changed)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
return clean_text(unicode_type(self.currentText()))
|
||||||
return clean_text(unicode_type(self.currentText()))
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val:
|
def current_val(self, val):
|
||||||
val = ''
|
if not val:
|
||||||
self.set_edit_text(val.strip())
|
val = ''
|
||||||
self.lineEdit().setCursorPosition(0)
|
self.set_edit_text(val.strip())
|
||||||
|
self.lineEdit().setCursorPosition(0)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.books_to_refresh = set([])
|
self.books_to_refresh = set([])
|
||||||
@ -672,19 +663,17 @@ class SeriesIndexEdit(make_undoable(QDoubleSpinBox), ToMetadataMixin):
|
|||||||
def enable(self, *args):
|
def enable(self, *args):
|
||||||
self.setEnabled(bool(self.series_edit.current_val))
|
self.setEnabled(bool(self.series_edit.current_val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
return self.value()
|
||||||
return self.value()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if val is None:
|
def current_val(self, val):
|
||||||
val = 1.0
|
if val is None:
|
||||||
val = float(val)
|
val = 1.0
|
||||||
self.set_spinbox_value(val)
|
val = float(val)
|
||||||
|
self.set_spinbox_value(val)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.db = db
|
self.db = db
|
||||||
@ -1255,31 +1244,29 @@ class Cover(ImageView): # {{{
|
|||||||
def changed(self):
|
def changed(self):
|
||||||
return self.current_val != self.original_val
|
return self.current_val != self.original_val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self._cdata
|
||||||
return self._cdata
|
|
||||||
|
|
||||||
def fset(self, cdata):
|
@current_val.setter
|
||||||
self._cdata = None
|
def current_val(self, cdata):
|
||||||
self.cdata_before_trim = None
|
self._cdata = None
|
||||||
pm = QPixmap()
|
self.cdata_before_trim = None
|
||||||
if cdata:
|
pm = QPixmap()
|
||||||
pm.loadFromData(cdata)
|
if cdata:
|
||||||
if pm.isNull():
|
pm.loadFromData(cdata)
|
||||||
pm = QPixmap(I('default_cover.png'))
|
if pm.isNull():
|
||||||
else:
|
pm = QPixmap(I('default_cover.png'))
|
||||||
self._cdata = cdata
|
else:
|
||||||
pm.setDevicePixelRatio(getattr(self, 'devicePixelRatioF', self.devicePixelRatio)())
|
self._cdata = cdata
|
||||||
self.setPixmap(pm)
|
pm.setDevicePixelRatio(getattr(self, 'devicePixelRatioF', self.devicePixelRatio)())
|
||||||
tt = _('This book has no cover')
|
self.setPixmap(pm)
|
||||||
if self._cdata:
|
tt = _('This book has no cover')
|
||||||
tt = _('Cover size: %(width)d x %(height)d pixels') % \
|
if self._cdata:
|
||||||
dict(width=pm.width(), height=pm.height())
|
tt = _('Cover size: %(width)d x %(height)d pixels') % \
|
||||||
self.setToolTip(tt)
|
dict(width=pm.width(), height=pm.height())
|
||||||
self.data_changed.emit()
|
self.setToolTip(tt)
|
||||||
|
self.data_changed.emit()
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
if self.changed:
|
if self.changed:
|
||||||
@ -1309,20 +1296,19 @@ class CommentsEdit(Editor, ToMetadataMixin): # {{{
|
|||||||
FIELD_NAME = 'comments'
|
FIELD_NAME = 'comments'
|
||||||
toolbar_prefs_name = 'metadata-comments-editor-widget-hidden-toolbars'
|
toolbar_prefs_name = 'metadata-comments-editor-widget-hidden-toolbars'
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.html
|
||||||
return self.html
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val or not val.strip():
|
def current_val(self, val):
|
||||||
val = ''
|
if not val or not val.strip():
|
||||||
else:
|
val = ''
|
||||||
val = comments_to_html(val)
|
else:
|
||||||
self.set_html(val, self.allow_undo)
|
val = comments_to_html(val)
|
||||||
self.wyswyg_dirtied()
|
self.set_html(val, self.allow_undo)
|
||||||
self.data_changed.emit()
|
self.wyswyg_dirtied()
|
||||||
return property(fget=fget, fset=fset)
|
self.data_changed.emit()
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
path = db.abspath(id_, index_is_id=True)
|
path = db.abspath(id_, index_is_id=True)
|
||||||
@ -1350,14 +1336,13 @@ class RatingEdit(RatingEditor, ToMetadataMixin): # {{{
|
|||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
self.currentTextChanged.connect(self.data_changed)
|
self.currentTextChanged.connect(self.data_changed)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.rating_value
|
||||||
return self.rating_value
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.rating_value = val
|
def current_val(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.rating_value = val
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
val = db.rating(id_, index_is_id=True)
|
val = db.rating(id_, index_is_id=True)
|
||||||
@ -1390,17 +1375,16 @@ class TagsEdit(EditWithComplete, ToMetadataMixin): # {{{
|
|||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return [clean_text(x) for x in unicode_type(self.text()).split(',')]
|
||||||
return [clean_text(x) for x in unicode_type(self.text()).split(',')]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val:
|
def current_val(self, val):
|
||||||
val = []
|
if not val:
|
||||||
self.set_edit_text(', '.join([x.strip() for x in val]))
|
val = []
|
||||||
self.setCursorPosition(0)
|
self.set_edit_text(', '.join([x.strip() for x in val]))
|
||||||
return property(fget=fget, fset=fset)
|
self.setCursorPosition(0)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.books_to_refresh = set([])
|
self.books_to_refresh = set([])
|
||||||
@ -1454,14 +1438,13 @@ class LanguagesEdit(LE, ToMetadataMixin): # {{{
|
|||||||
self.textChanged.connect(self.data_changed)
|
self.textChanged.connect(self.data_changed)
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.lang_codes
|
||||||
return self.lang_codes
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.set_lang_codes(val, self.allow_undo)
|
def current_val(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.set_lang_codes(val, self.allow_undo)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.init_langs(db)
|
self.init_langs(db)
|
||||||
@ -1562,44 +1545,43 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin):
|
|||||||
if d.exec_() == d.Accepted:
|
if d.exec_() == d.Accepted:
|
||||||
self.current_val = d.get_identifiers()
|
self.current_val = d.get_identifiers()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
raw = unicode_type(self.text()).strip()
|
||||||
raw = unicode_type(self.text()).strip()
|
parts = [clean_text(x) for x in raw.split(',')]
|
||||||
parts = [clean_text(x) for x in raw.split(',')]
|
ans = {}
|
||||||
ans = {}
|
for x in parts:
|
||||||
for x in parts:
|
c = x.split(':')
|
||||||
c = x.split(':')
|
if len(c) > 1:
|
||||||
if len(c) > 1:
|
itype = c[0].lower()
|
||||||
itype = c[0].lower()
|
c = ':'.join(c[1:])
|
||||||
c = ':'.join(c[1:])
|
if itype == 'isbn':
|
||||||
if itype == 'isbn':
|
v = check_isbn(c)
|
||||||
v = check_isbn(c)
|
|
||||||
if v is not None:
|
|
||||||
c = v
|
|
||||||
ans[itype] = c
|
|
||||||
return ans
|
|
||||||
|
|
||||||
def fset(self, val):
|
|
||||||
if not val:
|
|
||||||
val = {}
|
|
||||||
|
|
||||||
def keygen(x):
|
|
||||||
x = x[0]
|
|
||||||
if x == 'isbn':
|
|
||||||
x = '00isbn'
|
|
||||||
return x
|
|
||||||
for k in list(val):
|
|
||||||
if k == 'isbn':
|
|
||||||
v = check_isbn(k)
|
|
||||||
if v is not None:
|
if v is not None:
|
||||||
val[k] = v
|
c = v
|
||||||
ids = sorted(iteritems(val), key=keygen)
|
ans[itype] = c
|
||||||
txt = ', '.join(['%s:%s'%(k.lower(), vl) for k, vl in ids])
|
return ans
|
||||||
# Use selectAll + insert instead of setText so that undo works
|
|
||||||
self.selectAll(), self.insert(txt.strip())
|
@current_val.setter
|
||||||
self.setCursorPosition(0)
|
def current_val(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
if not val:
|
||||||
|
val = {}
|
||||||
|
|
||||||
|
def keygen(x):
|
||||||
|
x = x[0]
|
||||||
|
if x == 'isbn':
|
||||||
|
x = '00isbn'
|
||||||
|
return x
|
||||||
|
for k in list(val):
|
||||||
|
if k == 'isbn':
|
||||||
|
v = check_isbn(k)
|
||||||
|
if v is not None:
|
||||||
|
val[k] = v
|
||||||
|
ids = sorted(iteritems(val), key=keygen)
|
||||||
|
txt = ', '.join(['%s:%s'%(k.lower(), vl) for k, vl in ids])
|
||||||
|
# Use selectAll + insert instead of setText so that undo works
|
||||||
|
self.selectAll(), self.insert(txt.strip())
|
||||||
|
self.setCursorPosition(0)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.original_val = db.get_identifiers(id_, index_is_id=True)
|
self.original_val = db.get_identifiers(id_, index_is_id=True)
|
||||||
@ -1778,19 +1760,17 @@ class PublisherEdit(EditWithComplete, ToMetadataMixin): # {{{
|
|||||||
self.clear_button.setToolTip(_('Clear publisher'))
|
self.clear_button.setToolTip(_('Clear publisher'))
|
||||||
self.clear_button.clicked.connect(self.clearEditText)
|
self.clear_button.clicked.connect(self.clearEditText)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
|
|
||||||
def fget(self):
|
return clean_text(unicode_type(self.currentText()))
|
||||||
return clean_text(unicode_type(self.currentText()))
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if not val:
|
def current_val(self, val):
|
||||||
val = ''
|
if not val:
|
||||||
self.set_edit_text(val.strip())
|
val = ''
|
||||||
self.lineEdit().setCursorPosition(0)
|
self.set_edit_text(val.strip())
|
||||||
|
self.lineEdit().setCursorPosition(0)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.books_to_refresh = set([])
|
self.books_to_refresh = set([])
|
||||||
@ -1857,18 +1837,17 @@ class DateEdit(make_undoable(QDateTimeEdit), ToMetadataMixin):
|
|||||||
def reset_date(self, *args):
|
def reset_date(self, *args):
|
||||||
self.current_val = None
|
self.current_val = None
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return qt_to_dt(self.dateTime(), as_utc=False)
|
||||||
return qt_to_dt(self.dateTime(), as_utc=False)
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
if val is None or is_date_undefined(val):
|
def current_val(self, val):
|
||||||
val = UNDEFINED_DATE
|
if val is None or is_date_undefined(val):
|
||||||
else:
|
val = UNDEFINED_DATE
|
||||||
val = as_local_time(val)
|
else:
|
||||||
self.set_spinbox_value(val)
|
val = as_local_time(val)
|
||||||
return property(fget=fget, fset=fset)
|
self.set_spinbox_value(val)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
self.current_val = getattr(db, self.ATTR)(id_, index_is_id=True)
|
self.current_val = getattr(db, self.ATTR)(id_, index_is_id=True)
|
||||||
|
@ -49,29 +49,28 @@ class LineEdit(EditWithComplete):
|
|||||||
self.set_separator(sep)
|
self.set_separator(sep)
|
||||||
self.textChanged.connect(self.changed)
|
self.textChanged.connect(self.changed)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
def fget(self):
|
val = unicode_type(self.text()).strip()
|
||||||
val = unicode_type(self.text()).strip()
|
ism = self.metadata['is_multiple']
|
||||||
ism = self.metadata['is_multiple']
|
if ism:
|
||||||
if ism:
|
if not val:
|
||||||
if not val:
|
val = []
|
||||||
val = []
|
else:
|
||||||
else:
|
val = val.strip(ism['list_to_ui'].strip())
|
||||||
val = val.strip(ism['list_to_ui'].strip())
|
val = [x.strip() for x in val.split(ism['list_to_ui']) if x.strip()]
|
||||||
val = [x.strip() for x in val.split(ism['list_to_ui']) if x.strip()]
|
return val
|
||||||
return val
|
|
||||||
|
|
||||||
def fset(self, val):
|
@value.setter
|
||||||
ism = self.metadata['is_multiple']
|
def value(self, val):
|
||||||
if ism:
|
ism = self.metadata['is_multiple']
|
||||||
if not val:
|
if ism:
|
||||||
val = ''
|
if not val:
|
||||||
else:
|
val = ''
|
||||||
val = ism['list_to_ui'].join(val)
|
else:
|
||||||
self.setText(val)
|
val = ism['list_to_ui'].join(val)
|
||||||
self.setCursorPosition(0)
|
self.setText(val)
|
||||||
return property(fget=fget, fset=fset)
|
self.setCursorPosition(0)
|
||||||
|
|
||||||
def from_mi(self, mi):
|
def from_mi(self, mi):
|
||||||
val = mi.get(self.field, default='') or ''
|
val = mi.get(self.field, default='') or ''
|
||||||
@ -85,15 +84,14 @@ class LineEdit(EditWithComplete):
|
|||||||
elif self.field == 'authors':
|
elif self.field == 'authors':
|
||||||
mi.set('author_sort', authors_to_sort_string(val))
|
mi.set('author_sort', authors_to_sort_string(val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return unicode_type(self.text())
|
||||||
return unicode_type(self.text())
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.setText(val)
|
def current_val(self, val):
|
||||||
self.setCursorPosition(0)
|
self.setText(val)
|
||||||
return property(fget=fget, fset=fset)
|
self.setCursorPosition(0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_blank(self):
|
def is_blank(self):
|
||||||
@ -119,14 +117,13 @@ class LanguagesEdit(LE):
|
|||||||
if not is_new:
|
if not is_new:
|
||||||
self.lineEdit().setReadOnly(True)
|
self.lineEdit().setReadOnly(True)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.lang_codes
|
||||||
return self.lang_codes
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.lang_codes = val
|
def current_val(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.lang_codes = val
|
||||||
|
|
||||||
def from_mi(self, mi):
|
def from_mi(self, mi):
|
||||||
self.lang_codes = mi.languages
|
self.lang_codes = mi.languages
|
||||||
@ -241,17 +238,16 @@ class IdentifiersEdit(LineEdit):
|
|||||||
def to_mi(self, mi):
|
def to_mi(self, mi):
|
||||||
mi.set_identifiers(self.as_dict)
|
mi.set_identifiers(self.as_dict)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def as_dict(self):
|
def as_dict(self):
|
||||||
def fget(self):
|
parts = (x.strip() for x in self.current_val.split(',') if x.strip())
|
||||||
parts = (x.strip() for x in self.current_val.split(',') if x.strip())
|
return {k:v for k, v in iteritems({x.partition(':')[0].strip():x.partition(':')[-1].strip() for x in parts}) if k and v}
|
||||||
return {k:v for k, v in iteritems({x.partition(':')[0].strip():x.partition(':')[-1].strip() for x in parts}) if k and v}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@as_dict.setter
|
||||||
val = ('%s:%s' % (k, v) for k, v in iteritems(val))
|
def as_dict(self, val):
|
||||||
self.setText(', '.join(val))
|
val = ('%s:%s' % (k, v) for k, v in iteritems(val))
|
||||||
self.setCursorPosition(0)
|
self.setText(', '.join(val))
|
||||||
return property(fget=fget, fset=fset)
|
self.setCursorPosition(0)
|
||||||
|
|
||||||
|
|
||||||
class CommentsEdit(Editor):
|
class CommentsEdit(Editor):
|
||||||
@ -269,15 +265,14 @@ class CommentsEdit(Editor):
|
|||||||
self.hide_toolbars()
|
self.hide_toolbars()
|
||||||
self.set_readonly(True)
|
self.set_readonly(True)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.html
|
||||||
return self.html
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.html = val or ''
|
def current_val(self, val):
|
||||||
self.changed.emit()
|
self.html = val or ''
|
||||||
return property(fget=fget, fset=fset)
|
self.changed.emit()
|
||||||
|
|
||||||
def from_mi(self, mi):
|
def from_mi(self, mi):
|
||||||
val = mi.get(self.field, default='')
|
val = mi.get(self.field, default='')
|
||||||
@ -315,16 +310,15 @@ class CoverView(QWidget):
|
|||||||
def is_blank(self):
|
def is_blank(self):
|
||||||
return self.pixmap is None
|
return self.pixmap is None
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
return self.pixmap
|
||||||
return self.pixmap
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_val.setter
|
||||||
self.pixmap = val
|
def current_val(self, val):
|
||||||
self.changed.emit()
|
self.pixmap = val
|
||||||
self.update()
|
self.changed.emit()
|
||||||
return property(fget=fget, fset=fset)
|
self.update()
|
||||||
|
|
||||||
def from_mi(self, mi):
|
def from_mi(self, mi):
|
||||||
p = getattr(mi, 'cover', None)
|
p = getattr(mi, 'cover', None)
|
||||||
|
@ -138,35 +138,33 @@ class ConditionEditor(QWidget): # {{{
|
|||||||
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
|
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
|
||||||
b.setMinimumContentsLength(20)
|
b.setMinimumContentsLength(20)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_col(self):
|
def current_col(self):
|
||||||
def fget(self):
|
idx = self.column_box.currentIndex()
|
||||||
idx = self.column_box.currentIndex()
|
return unicode_type(self.column_box.itemData(idx) or '')
|
||||||
return unicode_type(self.column_box.itemData(idx) or '')
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_col.setter
|
||||||
for idx in range(self.column_box.count()):
|
def current_col(self, val):
|
||||||
c = unicode_type(self.column_box.itemData(idx) or '')
|
for idx in range(self.column_box.count()):
|
||||||
if c == val:
|
c = unicode_type(self.column_box.itemData(idx) or '')
|
||||||
self.column_box.setCurrentIndex(idx)
|
if c == val:
|
||||||
return
|
self.column_box.setCurrentIndex(idx)
|
||||||
raise ValueError('Column %r not found'%val)
|
return
|
||||||
return property(fget=fget, fset=fset)
|
raise ValueError('Column %r not found'%val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_action(self):
|
def current_action(self):
|
||||||
def fget(self):
|
idx = self.action_box.currentIndex()
|
||||||
idx = self.action_box.currentIndex()
|
return unicode_type(self.action_box.itemData(idx) or '')
|
||||||
return unicode_type(self.action_box.itemData(idx) or '')
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_action.setter
|
||||||
for idx in range(self.action_box.count()):
|
def current_action(self, val):
|
||||||
c = unicode_type(self.action_box.itemData(idx) or '')
|
for idx in range(self.action_box.count()):
|
||||||
if c == val:
|
c = unicode_type(self.action_box.itemData(idx) or '')
|
||||||
self.action_box.setCurrentIndex(idx)
|
if c == val:
|
||||||
return
|
self.action_box.setCurrentIndex(idx)
|
||||||
raise ValueError('Action %r not valid for current column'%val)
|
return
|
||||||
return property(fget=fget, fset=fset)
|
raise ValueError('Action %r not valid for current column'%val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
@ -176,26 +174,24 @@ class ConditionEditor(QWidget): # {{{
|
|||||||
ans = rmap.get(lower(ans), ans)
|
ans = rmap.get(lower(ans), ans)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def condition(self):
|
def condition(self):
|
||||||
|
|
||||||
def fget(self):
|
c, a, v = (self.current_col, self.current_action,
|
||||||
c, a, v = (self.current_col, self.current_action,
|
self.current_val)
|
||||||
self.current_val)
|
if not c or not a:
|
||||||
if not c or not a:
|
return None
|
||||||
return None
|
return (c, a, v)
|
||||||
return (c, a, v)
|
|
||||||
|
|
||||||
def fset(self, condition):
|
@condition.setter
|
||||||
c, a, v = condition
|
def condition(self, condition):
|
||||||
if not v:
|
c, a, v = condition
|
||||||
v = ''
|
if not v:
|
||||||
v = v.strip()
|
v = ''
|
||||||
self.current_col = c
|
v = v.strip()
|
||||||
self.current_action = a
|
self.current_col = c
|
||||||
self.value_box.setText(v)
|
self.current_action = a
|
||||||
|
self.value_box.setText(v)
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def init_action_box(self):
|
def init_action_box(self):
|
||||||
self.action_box.blockSignals(True)
|
self.action_box.blockSignals(True)
|
||||||
|
@ -62,23 +62,21 @@ class ResizeDialog(QDialog): # {{{
|
|||||||
other.setValue(oval)
|
other.setValue(oval)
|
||||||
other.blockSignals(False)
|
other.blockSignals(False)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def width(self):
|
def width(self):
|
||||||
def fget(self):
|
return self._width.value()
|
||||||
return self._width.value()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@width.setter
|
||||||
self._width.setValue(val)
|
def width(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._width.setValue(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def height(self):
|
def height(self):
|
||||||
def fget(self):
|
return self._height.value()
|
||||||
return self._height.value()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@height.setter
|
||||||
self._height.setValue(val)
|
def height(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._height.setValue(val)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
@ -111,24 +109,22 @@ class Editor(QMainWindow):
|
|||||||
self.canvas.undo_redo_state_changed.connect(self.undo_redo_state_changed)
|
self.canvas.undo_redo_state_changed.connect(self.undo_redo_state_changed)
|
||||||
self.canvas.selection_state_changed.connect(self.update_clipboard_actions)
|
self.canvas.selection_state_changed.connect(self.update_clipboard_actions)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def is_modified(self):
|
def is_modified(self):
|
||||||
def fget(self):
|
return self._is_modified
|
||||||
return self._is_modified
|
|
||||||
|
|
||||||
def fset(self, val):
|
@is_modified.setter
|
||||||
self._is_modified = val
|
def is_modified(self, val):
|
||||||
self.modification_state_changed.emit(val)
|
self._is_modified = val
|
||||||
return property(fget=fget, fset=fset)
|
self.modification_state_changed.emit(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_editing_state(self):
|
def current_editing_state(self):
|
||||||
def fget(self):
|
return {}
|
||||||
return {}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_editing_state.setter
|
||||||
pass
|
def current_editing_state(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def undo_available(self):
|
def undo_available(self):
|
||||||
@ -138,14 +134,13 @@ class Editor(QMainWindow):
|
|||||||
def redo_available(self):
|
def redo_available(self):
|
||||||
return self.canvas.redo_action.isEnabled()
|
return self.canvas.redo_action.isEnabled()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_line(self):
|
def current_line(self):
|
||||||
def fget(self):
|
return 0
|
||||||
return 0
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_line.setter
|
||||||
pass
|
def current_line(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number_of_lines(self):
|
def number_of_lines(self):
|
||||||
@ -160,15 +155,14 @@ class Editor(QMainWindow):
|
|||||||
def get_raw_data(self):
|
def get_raw_data(self):
|
||||||
return self.canvas.get_image_data(quality=self.quality)
|
return self.canvas.get_image_data(quality=self.quality)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
def fget(self):
|
return self.get_raw_data()
|
||||||
return self.get_raw_data()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@data.setter
|
||||||
self.canvas.load_image(val)
|
def data(self, val):
|
||||||
self._is_modified = False # The image_changed signal will have been triggered causing this editor to be incorrectly marked as modified
|
self.canvas.load_image(val)
|
||||||
return property(fget=fget, fset=fset)
|
self._is_modified = False # The image_changed signal will have been triggered causing this editor to be incorrectly marked as modified
|
||||||
|
|
||||||
def replace_data(self, raw, only_if_different=True):
|
def replace_data(self, raw, only_if_different=True):
|
||||||
# We ignore only_if_different as it is useless in our case, and
|
# We ignore only_if_different as it is useless in our case, and
|
||||||
|
@ -221,26 +221,25 @@ class EditorTabStop(object):
|
|||||||
with m:
|
with m:
|
||||||
m.text = text
|
m.text = text
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def text(self):
|
def text(self):
|
||||||
def fget(self):
|
editor = self.editor()
|
||||||
editor = self.editor()
|
if editor is None or self.is_deleted:
|
||||||
if editor is None or self.is_deleted:
|
return ''
|
||||||
return ''
|
c = editor.textCursor()
|
||||||
c = editor.textCursor()
|
c.setPosition(self.left), c.setPosition(self.right, c.KeepAnchor)
|
||||||
c.setPosition(self.left), c.setPosition(self.right, c.KeepAnchor)
|
return editor.selected_text_from_cursor(c)
|
||||||
return editor.selected_text_from_cursor(c)
|
|
||||||
|
|
||||||
def fset(self, text):
|
@text.setter
|
||||||
editor = self.editor()
|
def text(self, text):
|
||||||
if editor is None or self.is_deleted:
|
editor = self.editor()
|
||||||
return
|
if editor is None or self.is_deleted:
|
||||||
c = editor.textCursor()
|
return
|
||||||
c.joinPreviousEditBlock() if self.join_previous_edit else c.beginEditBlock()
|
c = editor.textCursor()
|
||||||
c.setPosition(self.left), c.setPosition(self.right, c.KeepAnchor)
|
c.joinPreviousEditBlock() if self.join_previous_edit else c.beginEditBlock()
|
||||||
c.insertText(text)
|
c.setPosition(self.left), c.setPosition(self.right, c.KeepAnchor)
|
||||||
c.endEditBlock()
|
c.insertText(text)
|
||||||
return property(fget=fget, fset=fset)
|
c.endEditBlock()
|
||||||
|
|
||||||
def set_editor_cursor(self, editor):
|
def set_editor_cursor(self, editor):
|
||||||
if not self.is_deleted:
|
if not self.is_deleted:
|
||||||
@ -537,20 +536,18 @@ class EditSnippet(QWidget):
|
|||||||
self.types.item(0).setCheckState(Qt.Checked)
|
self.types.item(0).setCheckState(Qt.Checked)
|
||||||
(self.name if self.creating_snippet else self.template).setFocus(Qt.OtherFocusReason)
|
(self.name if self.creating_snippet else self.template).setFocus(Qt.OtherFocusReason)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def snip(self):
|
def snip(self):
|
||||||
def fset(self, snip):
|
ftypes = []
|
||||||
self.apply_snip(snip)
|
for i in range(self.types.count()):
|
||||||
|
i = self.types.item(i)
|
||||||
|
if i.checkState() == Qt.Checked:
|
||||||
|
ftypes.append(i.data(Qt.UserRole))
|
||||||
|
return {'description':self.name.text().strip(), 'trigger':self.trig.text(), 'template':self.template.toPlainText(), 'syntaxes':ftypes}
|
||||||
|
|
||||||
def fget(self):
|
@snip.setter
|
||||||
ftypes = []
|
def snip(self, snip):
|
||||||
for i in range(self.types.count()):
|
self.apply_snip(snip)
|
||||||
i = self.types.item(i)
|
|
||||||
if i.checkState() == Qt.Checked:
|
|
||||||
ftypes.append(i.data(Qt.UserRole))
|
|
||||||
return {'description':self.name.text().strip(), 'trigger':self.trig.text(), 'template':self.template.toPlainText(), 'syntaxes':ftypes}
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
snip = self.snip
|
snip = self.snip
|
||||||
|
@ -206,17 +206,15 @@ class TextEdit(PlainTextEdit):
|
|||||||
insert_text(md.html())
|
insert_text(md.html())
|
||||||
return
|
return
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def is_modified(self):
|
def is_modified(self):
|
||||||
''' True if the document has been modified since it was loaded or since
|
''' True if the document has been modified since it was loaded or since
|
||||||
the last time is_modified was set to False. '''
|
the last time is_modified was set to False. '''
|
||||||
|
return self.document().isModified()
|
||||||
|
|
||||||
def fget(self):
|
@is_modified.setter
|
||||||
return self.document().isModified()
|
def is_modified(self, val):
|
||||||
|
self.document().setModified(bool(val))
|
||||||
def fset(self, val):
|
|
||||||
self.document().setModified(bool(val))
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return self.size_hint
|
return self.size_hint
|
||||||
|
@ -159,28 +159,26 @@ class Editor(QMainWindow):
|
|||||||
self.editor.link_clicked.connect(self.link_clicked)
|
self.editor.link_clicked.connect(self.link_clicked)
|
||||||
self.editor.smart_highlighting_updated.connect(self.smart_highlighting_updated)
|
self.editor.smart_highlighting_updated.connect(self.smart_highlighting_updated)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_line(self):
|
def current_line(self):
|
||||||
def fget(self):
|
return self.editor.textCursor().blockNumber()
|
||||||
return self.editor.textCursor().blockNumber()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_line.setter
|
||||||
self.editor.go_to_line(val)
|
def current_line(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.editor.go_to_line(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_editing_state(self):
|
def current_editing_state(self):
|
||||||
def fget(self):
|
c = self.editor.textCursor()
|
||||||
c = self.editor.textCursor()
|
return {'cursor':(c.anchor(), c.position())}
|
||||||
return {'cursor':(c.anchor(), c.position())}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_editing_state.setter
|
||||||
anchor, position = val.get('cursor', (None, None))
|
def current_editing_state(self, val):
|
||||||
if anchor is not None and position is not None:
|
anchor, position = val.get('cursor', (None, None))
|
||||||
c = self.editor.textCursor()
|
if anchor is not None and position is not None:
|
||||||
c.setPosition(anchor), c.setPosition(position, c.KeepAnchor)
|
c = self.editor.textCursor()
|
||||||
self.editor.setTextCursor(c)
|
c.setPosition(anchor), c.setPosition(position, c.KeepAnchor)
|
||||||
return property(fget=fget, fset=fset)
|
self.editor.setTextCursor(c)
|
||||||
|
|
||||||
def current_tag(self, for_position_sync=True):
|
def current_tag(self, for_position_sync=True):
|
||||||
return self.editor.current_tag(for_position_sync=for_position_sync)
|
return self.editor.current_tag(for_position_sync=for_position_sync)
|
||||||
@ -189,18 +187,17 @@ class Editor(QMainWindow):
|
|||||||
def number_of_lines(self):
|
def number_of_lines(self):
|
||||||
return self.editor.blockCount()
|
return self.editor.blockCount()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
def fget(self):
|
ans = self.get_raw_data()
|
||||||
ans = self.get_raw_data()
|
ans, changed = replace_encoding_declarations(ans, enc='utf-8', limit=4*1024)
|
||||||
ans, changed = replace_encoding_declarations(ans, enc='utf-8', limit=4*1024)
|
if changed:
|
||||||
if changed:
|
self.data = ans
|
||||||
self.data = ans
|
return ans.encode('utf-8')
|
||||||
return ans.encode('utf-8')
|
|
||||||
|
|
||||||
def fset(self, val):
|
@data.setter
|
||||||
self.editor.load_text(val, syntax=self.syntax, doc_name=editor_name(self))
|
def data(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.editor.load_text(val, syntax=self.syntax, doc_name=editor_name(self))
|
||||||
|
|
||||||
def init_from_template(self, template):
|
def init_from_template(self, template):
|
||||||
self.editor.load_text(template, syntax=self.syntax, process_template=True, doc_name=editor_name(self))
|
self.editor.load_text(template, syntax=self.syntax, process_template=True, doc_name=editor_name(self))
|
||||||
@ -317,14 +314,13 @@ class Editor(QMainWindow):
|
|||||||
def has_marked_text(self):
|
def has_marked_text(self):
|
||||||
return self.editor.current_search_mark is not None
|
return self.editor.current_search_mark is not None
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def is_modified(self):
|
def is_modified(self):
|
||||||
def fget(self):
|
return self.editor.is_modified
|
||||||
return self.editor.is_modified
|
|
||||||
|
|
||||||
def fset(self, val):
|
@is_modified.setter
|
||||||
self.editor.is_modified = val
|
def is_modified(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.editor.is_modified = val
|
||||||
|
|
||||||
def create_toolbars(self):
|
def create_toolbars(self):
|
||||||
self.action_bar = b = self.addToolBar(_('Edit actions tool bar'))
|
self.action_bar = b = self.addToolBar(_('Edit actions tool bar'))
|
||||||
|
@ -370,17 +370,16 @@ class WebView(QWebView):
|
|||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.pageAction(self.page().Reload).trigger()
|
self.pageAction(self.page().Reload).trigger()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def scroll_pos(self):
|
def scroll_pos(self):
|
||||||
def fget(self):
|
mf = self.page().mainFrame()
|
||||||
mf = self.page().mainFrame()
|
return (mf.scrollBarValue(Qt.Horizontal), mf.scrollBarValue(Qt.Vertical))
|
||||||
return (mf.scrollBarValue(Qt.Horizontal), mf.scrollBarValue(Qt.Vertical))
|
|
||||||
|
|
||||||
def fset(self, val):
|
@scroll_pos.setter
|
||||||
mf = self.page().mainFrame()
|
def scroll_pos(self, val):
|
||||||
mf.setScrollBarValue(Qt.Horizontal, val[0])
|
mf = self.page().mainFrame()
|
||||||
mf.setScrollBarValue(Qt.Vertical, val[1])
|
mf.setScrollBarValue(Qt.Horizontal, val[0])
|
||||||
return property(fget=fget, fset=fset)
|
mf.setScrollBarValue(Qt.Vertical, val[1])
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.setHtml(_(
|
self.setHtml(_(
|
||||||
|
@ -1061,14 +1061,13 @@ class CSSWidget(QWidget):
|
|||||||
self.summary = la = QLabel('\xa0')
|
self.summary = la = QLabel('\xa0')
|
||||||
h.addWidget(la)
|
h.addWidget(la)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def sort_order(self):
|
def sort_order(self):
|
||||||
def fget(self):
|
return [Qt.AscendingOrder, Qt.DescendingOrder][self._sort_order.currentIndex()]
|
||||||
return [Qt.AscendingOrder, Qt.DescendingOrder][self._sort_order.currentIndex()]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@sort_order.setter
|
||||||
self._sort_order.setCurrentIndex({Qt.AscendingOrder:0}.get(val, 1))
|
def sort_order(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._sort_order.setCurrentIndex({Qt.AscendingOrder:0}.get(val, 1))
|
||||||
|
|
||||||
def update_summary(self):
|
def update_summary(self):
|
||||||
self.summary.setText(_('{0} rules, {1} unused').format(self.model.rowCount(), self.model.num_unused))
|
self.summary.setText(_('{0} rules, {1} unused').format(self.model.rowCount(), self.model.num_unused))
|
||||||
|
@ -152,16 +152,15 @@ class WhereBox(QComboBox):
|
|||||||
f.setBold(True), f.setItalic(True)
|
f.setBold(True), f.setItalic(True)
|
||||||
self.setFont(f)
|
self.setFont(f)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def where(self):
|
def where(self):
|
||||||
wm = {0:'current', 1:'text', 2:'styles', 3:'selected', 4:'open', 5:'selected-text'}
|
wm = {0:'current', 1:'text', 2:'styles', 3:'selected', 4:'open', 5:'selected-text'}
|
||||||
|
return wm[self.currentIndex()]
|
||||||
|
|
||||||
def fget(self):
|
@where.setter
|
||||||
return wm[self.currentIndex()]
|
def where(self, val):
|
||||||
|
wm = {0:'current', 1:'text', 2:'styles', 3:'selected', 4:'open', 5:'selected-text'}
|
||||||
def fset(self, val):
|
self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
|
||||||
self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def showPopup(self):
|
def showPopup(self):
|
||||||
# We do it like this so that the popup uses a normal font
|
# We do it like this so that the popup uses a normal font
|
||||||
@ -190,14 +189,13 @@ class DirectionBox(QComboBox):
|
|||||||
<dd>Search for the previous match from your current position</dd>
|
<dd>Search for the previous match from your current position</dd>
|
||||||
</dl>'''))
|
</dl>'''))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def direction(self):
|
def direction(self):
|
||||||
def fget(self):
|
return 'down' if self.currentIndex() == 0 else 'up'
|
||||||
return 'down' if self.currentIndex() == 0 else 'up'
|
|
||||||
|
|
||||||
def fset(self, val):
|
@direction.setter
|
||||||
self.setCurrentIndex(1 if val == 'up' else 0)
|
def direction(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.setCurrentIndex(1 if val == 'up' else 0)
|
||||||
|
|
||||||
|
|
||||||
class ModeBox(QComboBox):
|
class ModeBox(QComboBox):
|
||||||
@ -216,14 +214,13 @@ class ModeBox(QComboBox):
|
|||||||
<dd>The search expression is interpreted as a regular expression. The replace expression is an arbitrarily powerful Python function.</dd>
|
<dd>The search expression is interpreted as a regular expression. The replace expression is an arbitrarily powerful Python function.</dd>
|
||||||
</dl>'''))
|
</dl>'''))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def mode(self):
|
def mode(self):
|
||||||
def fget(self):
|
return ('normal', 'regex', 'function')[self.currentIndex()]
|
||||||
return ('normal', 'regex', 'function')[self.currentIndex()]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@mode.setter
|
||||||
self.setCurrentIndex({'regex':1, 'function':2}.get(val, 0))
|
def mode(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.setCurrentIndex({'regex':1, 'function':2}.get(val, 0))
|
||||||
|
|
||||||
|
|
||||||
class SearchWidget(QWidget):
|
class SearchWidget(QWidget):
|
||||||
@ -353,91 +350,82 @@ class SearchWidget(QWidget):
|
|||||||
self.replace_text.setVisible(not function_mode)
|
self.replace_text.setVisible(not function_mode)
|
||||||
self.functions_container.setVisible(function_mode)
|
self.functions_container.setVisible(function_mode)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def mode(self):
|
def mode(self):
|
||||||
def fget(self):
|
return self.mode_box.mode
|
||||||
return self.mode_box.mode
|
|
||||||
|
|
||||||
def fset(self, val):
|
@mode.setter
|
||||||
self.mode_box.mode = val
|
def mode(self, val):
|
||||||
self.da.setVisible(self.mode in ('regex', 'function'))
|
self.mode_box.mode = val
|
||||||
return property(fget=fget, fset=fset)
|
self.da.setVisible(self.mode in ('regex', 'function'))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def find(self):
|
def find(self):
|
||||||
def fget(self):
|
return unicode_type(self.find_text.text())
|
||||||
return unicode_type(self.find_text.text())
|
|
||||||
|
|
||||||
def fset(self, val):
|
@find.setter
|
||||||
self.find_text.setText(val)
|
def find(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.find_text.setText(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def replace(self):
|
def replace(self):
|
||||||
def fget(self):
|
if self.mode == 'function':
|
||||||
if self.mode == 'function':
|
return self.functions.text()
|
||||||
return self.functions.text()
|
return unicode_type(self.replace_text.text())
|
||||||
return unicode_type(self.replace_text.text())
|
|
||||||
|
|
||||||
def fset(self, val):
|
@replace.setter
|
||||||
self.replace_text.setText(val)
|
def replace(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.replace_text.setText(val)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def where(self):
|
def where(self):
|
||||||
def fget(self):
|
return self.where_box.where
|
||||||
return self.where_box.where
|
|
||||||
|
|
||||||
def fset(self, val):
|
@where.setter
|
||||||
self.where_box.where = val
|
def where(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.where_box.where = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def case_sensitive(self):
|
def case_sensitive(self):
|
||||||
def fget(self):
|
return self.cs.isChecked()
|
||||||
return self.cs.isChecked()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@case_sensitive.setter
|
||||||
self.cs.setChecked(bool(val))
|
def case_sensitive(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.cs.setChecked(bool(val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def direction(self):
|
def direction(self):
|
||||||
def fget(self):
|
return self.direction_box.direction
|
||||||
return self.direction_box.direction
|
|
||||||
|
|
||||||
def fset(self, val):
|
@direction.setter
|
||||||
self.direction_box.direction = val
|
def direction(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.direction_box.direction = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def wrap(self):
|
def wrap(self):
|
||||||
def fget(self):
|
return self.wr.isChecked()
|
||||||
return self.wr.isChecked()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@wrap.setter
|
||||||
self.wr.setChecked(bool(val))
|
def wrap(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.wr.setChecked(bool(val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def dot_all(self):
|
def dot_all(self):
|
||||||
def fget(self):
|
return self.da.isChecked()
|
||||||
return self.da.isChecked()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@dot_all.setter
|
||||||
self.da.setChecked(bool(val))
|
def dot_all(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.da.setChecked(bool(val))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
def fget(self):
|
return {x:getattr(self, x) for x in self.DEFAULT_STATE}
|
||||||
return {x:getattr(self, x) for x in self.DEFAULT_STATE}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@state.setter
|
||||||
for x in self.DEFAULT_STATE:
|
def state(self, val):
|
||||||
if x in val:
|
for x in self.DEFAULT_STATE:
|
||||||
setattr(self, x, val[x])
|
if x in val:
|
||||||
return property(fget=fget, fset=fset)
|
setattr(self, x, val[x])
|
||||||
|
|
||||||
def restore_state(self):
|
def restore_state(self):
|
||||||
self.state = tprefs.get('find-widget-state', self.DEFAULT_STATE)
|
self.state = tprefs.get('find-widget-state', self.DEFAULT_STATE)
|
||||||
@ -1008,14 +996,13 @@ class SavedSearches(QWidget):
|
|||||||
|
|
||||||
self.searches.setFocus(Qt.OtherFocusReason)
|
self.searches.setFocus(Qt.OtherFocusReason)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
def fget(self):
|
return {'wrap':self.wrap, 'direction':self.direction, 'where':self.where}
|
||||||
return {'wrap':self.wrap, 'direction':self.direction, 'where':self.where}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@state.setter
|
||||||
self.wrap, self.where, self.direction = val['wrap'], val['where'], val['direction']
|
def state(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.wrap, self.where, self.direction = val['wrap'], val['where'], val['direction']
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
tprefs['saved_seaches_state'] = self.state
|
tprefs['saved_seaches_state'] = self.state
|
||||||
@ -1042,32 +1029,29 @@ class SavedSearches(QWidget):
|
|||||||
for x in ('eb', 'ab', 'rb', 'upb', 'dnb', 'd2', 'filter_text', 'cft', 'd3', 'ib', 'eb2'):
|
for x in ('eb', 'ab', 'rb', 'upb', 'dnb', 'd2', 'filter_text', 'cft', 'd3', 'ib', 'eb2'):
|
||||||
getattr(self, x).setVisible(visible)
|
getattr(self, x).setVisible(visible)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def where(self):
|
def where(self):
|
||||||
def fget(self):
|
return self.where_box.where
|
||||||
return self.where_box.where
|
|
||||||
|
|
||||||
def fset(self, val):
|
@where.setter
|
||||||
self.where_box.where = val
|
def where(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.where_box.where = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def direction(self):
|
def direction(self):
|
||||||
def fget(self):
|
return self.direction_box.direction
|
||||||
return self.direction_box.direction
|
|
||||||
|
|
||||||
def fset(self, val):
|
@direction.setter
|
||||||
self.direction_box.direction = val
|
def direction(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.direction_box.direction = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def wrap(self):
|
def wrap(self):
|
||||||
def fget(self):
|
return self.wr.isChecked()
|
||||||
return self.wr.isChecked()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@wrap.setter
|
||||||
self.wr.setChecked(bool(val))
|
def wrap(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.wr.setChecked(bool(val))
|
||||||
|
|
||||||
def do_filter(self, text):
|
def do_filter(self, text):
|
||||||
self.model.do_filter(text)
|
self.model.do_filter(text)
|
||||||
|
@ -36,14 +36,13 @@ class ModeBox(QComboBox):
|
|||||||
<dd>The search expression is interpreted as a regular expression. See the User Manual for more help on using regular expressions.</dd>
|
<dd>The search expression is interpreted as a regular expression. See the User Manual for more help on using regular expressions.</dd>
|
||||||
</dl>'''))
|
</dl>'''))
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def mode(self):
|
def mode(self):
|
||||||
def fget(self):
|
return ('normal', 'regex')[self.currentIndex()]
|
||||||
return ('normal', 'regex')[self.currentIndex()]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@mode.setter
|
||||||
self.setCurrentIndex({'regex':1}.get(val, 0))
|
def mode(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.setCurrentIndex({'regex':1}.get(val, 0))
|
||||||
|
|
||||||
|
|
||||||
class WhereBox(QComboBox):
|
class WhereBox(QComboBox):
|
||||||
@ -71,16 +70,15 @@ class WhereBox(QComboBox):
|
|||||||
f.setBold(True), f.setItalic(True)
|
f.setBold(True), f.setItalic(True)
|
||||||
self.setFont(f)
|
self.setFont(f)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def where(self):
|
def where(self):
|
||||||
wm = {0:'current', 1:'text', 2:'selected', 3:'open'}
|
wm = {0:'current', 1:'text', 2:'selected', 3:'open'}
|
||||||
|
return wm[self.currentIndex()]
|
||||||
|
|
||||||
def fget(self):
|
@where.setter
|
||||||
return wm[self.currentIndex()]
|
def where(self, val):
|
||||||
|
wm = {0:'current', 1:'text', 2:'selected', 3:'open'}
|
||||||
def fset(self, val):
|
self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
|
||||||
self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def showPopup(self):
|
def showPopup(self):
|
||||||
# We do it like this so that the popup uses a normal font
|
# We do it like this so that the popup uses a normal font
|
||||||
@ -137,17 +135,16 @@ class TextSearch(QWidget):
|
|||||||
state = tprefs.get('text_search_widget_state')
|
state = tprefs.get('text_search_widget_state')
|
||||||
self.state = state or {}
|
self.state = state or {}
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
def fget(self):
|
return {'mode': self.mode.mode, 'where':self.where_box.where, 'case_sensitive':self.cs.isChecked(), 'dot_all':self.da.isChecked()}
|
||||||
return {'mode': self.mode.mode, 'where':self.where_box.where, 'case_sensitive':self.cs.isChecked(), 'dot_all':self.da.isChecked()}
|
|
||||||
|
|
||||||
def fset(self, val):
|
@state.setter
|
||||||
self.mode.mode = val.get('mode', 'normal')
|
def state(self, val):
|
||||||
self.where_box.where = val.get('where', 'current')
|
self.mode.mode = val.get('mode', 'normal')
|
||||||
self.cs.setChecked(bool(val.get('case_sensitive')))
|
self.where_box.where = val.get('where', 'current')
|
||||||
self.da.setChecked(bool(val.get('dot_all', True)))
|
self.cs.setChecked(bool(val.get('case_sensitive')))
|
||||||
return property(fget=fget, fset=fset)
|
self.da.setChecked(bool(val.get('dot_all', True)))
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
tprefs['text_search_widget_state'] = self.state
|
tprefs['text_search_widget_state'] = self.state
|
||||||
|
@ -236,17 +236,16 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
|||||||
from calibre.gui2.viewer.main import dprefs
|
from calibre.gui2.viewer.main import dprefs
|
||||||
self.word_lookups = dprefs['word_lookups']
|
self.word_lookups = dprefs['word_lookups']
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def word_lookups(self):
|
def word_lookups(self):
|
||||||
def fget(self):
|
return dict(self.dictionary_list.item(i).data(Qt.UserRole) for i in range(self.dictionary_list.count()))
|
||||||
return dict(self.dictionary_list.item(i).data(Qt.UserRole) for i in range(self.dictionary_list.count()))
|
|
||||||
|
|
||||||
def fset(self, wl):
|
@word_lookups.setter
|
||||||
self.dictionary_list.clear()
|
def word_lookups(self, wl):
|
||||||
for langcode, url in sorted(iteritems(wl), key=lambda lc_url:sort_key(calibre_langcode_to_name(lc_url[0]))):
|
self.dictionary_list.clear()
|
||||||
i = QListWidgetItem('%s: %s' % (calibre_langcode_to_name(langcode), url), self.dictionary_list)
|
for langcode, url in sorted(iteritems(wl), key=lambda lc_url:sort_key(calibre_langcode_to_name(lc_url[0]))):
|
||||||
i.setData(Qt.UserRole, (langcode, url))
|
i = QListWidgetItem('%s: %s' % (calibre_langcode_to_name(langcode), url), self.dictionary_list)
|
||||||
return property(fget=fget, fset=fset)
|
i.setData(Qt.UserRole, (langcode, url))
|
||||||
|
|
||||||
def add_dictionary_website(self):
|
def add_dictionary_website(self):
|
||||||
class AD(QDialog):
|
class AD(QDialog):
|
||||||
|
@ -430,46 +430,43 @@ class Document(QWebPage): # {{{
|
|||||||
def xpos(self):
|
def xpos(self):
|
||||||
return self.mainFrame().scrollPosition().x()
|
return self.mainFrame().scrollPosition().x()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def scroll_fraction(self):
|
def scroll_fraction(self):
|
||||||
def fget(self):
|
if self.in_paged_mode:
|
||||||
if self.in_paged_mode:
|
return self.javascript('''
|
||||||
return self.javascript('''
|
ans = 0.0;
|
||||||
ans = 0.0;
|
if (window.paged_display) {
|
||||||
if (window.paged_display) {
|
ans = window.paged_display.current_pos();
|
||||||
ans = window.paged_display.current_pos();
|
}
|
||||||
}
|
ans;''', typ='float')
|
||||||
ans;''', typ='float')
|
else:
|
||||||
else:
|
try:
|
||||||
try:
|
return abs(float(self.ypos)/(self.height-self.window_height))
|
||||||
return abs(float(self.ypos)/(self.height-self.window_height))
|
except ZeroDivisionError:
|
||||||
except ZeroDivisionError:
|
return 0.
|
||||||
return 0.
|
|
||||||
|
|
||||||
def fset(self, val):
|
@scroll_fraction.setter
|
||||||
if self.in_paged_mode and self.loaded_javascript:
|
def scroll_fraction(self, val):
|
||||||
self.javascript('paged_display.scroll_to_pos(%f)'%val)
|
if self.in_paged_mode and self.loaded_javascript:
|
||||||
else:
|
self.javascript('paged_display.scroll_to_pos(%f)'%val)
|
||||||
npos = val * (self.height - self.window_height)
|
else:
|
||||||
if npos < 0:
|
npos = val * (self.height - self.window_height)
|
||||||
npos = 0
|
if npos < 0:
|
||||||
self.scroll_to(x=self.xpos, y=npos)
|
npos = 0
|
||||||
return property(fget=fget, fset=fset)
|
self.scroll_to(x=self.xpos, y=npos)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def page_number(self):
|
def page_number(self):
|
||||||
' The page number is the number of the page at the left most edge of the screen (starting from 0) '
|
' The page number is the number of the page at the left most edge of the screen (starting from 0) '
|
||||||
|
if self.in_paged_mode:
|
||||||
|
return self.javascript(
|
||||||
|
'ans = 0; if (window.paged_display) ans = window.paged_display.column_boundaries()[0]; ans;', typ='int')
|
||||||
|
|
||||||
def fget(self):
|
@page_number.setter
|
||||||
if self.in_paged_mode:
|
def page_number(self, val):
|
||||||
return self.javascript(
|
if self.in_paged_mode and self.loaded_javascript:
|
||||||
'ans = 0; if (window.paged_display) ans = window.paged_display.column_boundaries()[0]; ans;', typ='int')
|
self.javascript('if (window.paged_display) window.paged_display.scroll_to_column(%d)' % int(val))
|
||||||
|
return True
|
||||||
def fset(self, val):
|
|
||||||
if self.in_paged_mode and self.loaded_javascript:
|
|
||||||
self.javascript('if (window.paged_display) window.paged_display.scroll_to_column(%d)' % int(val))
|
|
||||||
return True
|
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def page_dimensions(self):
|
def page_dimensions(self):
|
||||||
@ -862,14 +859,13 @@ class DocumentView(QWebView): # {{{
|
|||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return self._size_hint
|
return self._size_hint
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def scroll_fraction(self):
|
def scroll_fraction(self):
|
||||||
def fget(self):
|
return self.document.scroll_fraction
|
||||||
return self.document.scroll_fraction
|
|
||||||
|
|
||||||
def fset(self, val):
|
@scroll_fraction.setter
|
||||||
self.document.scroll_fraction = float(val)
|
def scroll_fraction(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.document.scroll_fraction = float(val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hscroll_fraction(self):
|
def hscroll_fraction(self):
|
||||||
@ -879,14 +875,13 @@ class DocumentView(QWebView): # {{{
|
|||||||
def content_size(self):
|
def content_size(self):
|
||||||
return self.document.width, self.document.height
|
return self.document.width, self.document.height
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def current_language(self):
|
def current_language(self):
|
||||||
def fget(self):
|
return self.document.current_language
|
||||||
return self.document.current_language
|
|
||||||
|
|
||||||
def fset(self, val):
|
@current_language.setter
|
||||||
self.document.current_language = val
|
def current_language(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.document.current_language = val
|
||||||
|
|
||||||
def search(self, text, backwards=False):
|
def search(self, text, backwards=False):
|
||||||
flags = self.document.FindBackward if backwards else self.document.FindFlags(0)
|
flags = self.document.FindBackward if backwards else self.document.FindFlags(0)
|
||||||
@ -1189,19 +1184,18 @@ class DocumentView(QWebView): # {{{
|
|||||||
if notify and self.manager is not None and new_pos != old_pos:
|
if notify and self.manager is not None and new_pos != old_pos:
|
||||||
self.manager.scrolled(self.scroll_fraction)
|
self.manager.scrolled(self.scroll_fraction)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def multiplier(self):
|
def multiplier(self):
|
||||||
def fget(self):
|
return self.zoomFactor()
|
||||||
return self.zoomFactor()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@multiplier.setter
|
||||||
oval = self.zoomFactor()
|
def multiplier(self, val):
|
||||||
self.setZoomFactor(val)
|
oval = self.zoomFactor()
|
||||||
if val != oval:
|
self.setZoomFactor(val)
|
||||||
if self.document.in_paged_mode:
|
if val != oval:
|
||||||
self.document.update_contents_size_for_paged_mode()
|
if self.document.in_paged_mode:
|
||||||
self.magnification_changed.emit(val)
|
self.document.update_contents_size_for_paged_mode()
|
||||||
return property(fget=fget, fset=fset)
|
self.magnification_changed.emit(val)
|
||||||
|
|
||||||
def magnify_fonts(self, amount=None):
|
def magnify_fonts(self, amount=None):
|
||||||
if amount is None:
|
if amount is None:
|
||||||
|
@ -1131,30 +1131,28 @@ class Splitter(QSplitter):
|
|||||||
print(self.save_name, 'side:', self.side_index_size, 'other:', end=' ')
|
print(self.save_name, 'side:', self.side_index_size, 'other:', end=' ')
|
||||||
print(list(self.sizes())[self.other_index])
|
print(list(self.sizes())[self.other_index])
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def side_index_size(self):
|
def side_index_size(self):
|
||||||
def fget(self):
|
if self.count() < 2:
|
||||||
if self.count() < 2:
|
return 0
|
||||||
return 0
|
return self.sizes()[self.side_index]
|
||||||
return self.sizes()[self.side_index]
|
|
||||||
|
|
||||||
def fset(self, val):
|
@side_index_size.setter
|
||||||
if self.count() < 2:
|
def side_index_size(self, val):
|
||||||
return
|
if self.count() < 2:
|
||||||
if val == 0 and not self.is_side_index_hidden:
|
return
|
||||||
self.save_state()
|
if val == 0 and not self.is_side_index_hidden:
|
||||||
sizes = list(self.sizes())
|
self.save_state()
|
||||||
for i in range(len(sizes)):
|
sizes = list(self.sizes())
|
||||||
sizes[i] = val if i == self.side_index else 10
|
for i in range(len(sizes)):
|
||||||
self.setSizes(sizes)
|
sizes[i] = val if i == self.side_index else 10
|
||||||
total = sum(self.sizes())
|
self.setSizes(sizes)
|
||||||
sizes = list(self.sizes())
|
total = sum(self.sizes())
|
||||||
for i in range(len(sizes)):
|
sizes = list(self.sizes())
|
||||||
sizes[i] = val if i == self.side_index else total-val
|
for i in range(len(sizes)):
|
||||||
self.setSizes(sizes)
|
sizes[i] = val if i == self.side_index else total-val
|
||||||
self.initialize()
|
self.setSizes(sizes)
|
||||||
|
self.initialize()
|
||||||
return property(fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def do_resize(self, *args):
|
def do_resize(self, *args):
|
||||||
orig = self.desired_side_size
|
orig = self.desired_side_size
|
||||||
|
@ -86,28 +86,27 @@ class ColorButton(QPushButton):
|
|||||||
self.color = initial_color
|
self.color = initial_color
|
||||||
self.clicked.connect(self.choose_color)
|
self.clicked.connect(self.choose_color)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def color(self):
|
def color(self):
|
||||||
def fget(self):
|
return self._color
|
||||||
return self._color
|
|
||||||
|
|
||||||
def fset(self, val):
|
@color.setter
|
||||||
val = unicode_type(val or '')
|
def color(self, val):
|
||||||
col = QColor(val)
|
val = unicode_type(val or '')
|
||||||
orig = self._color
|
col = QColor(val)
|
||||||
if col.isValid():
|
orig = self._color
|
||||||
self._color = val
|
if col.isValid():
|
||||||
self.setText(val)
|
self._color = val
|
||||||
p = QPixmap(self.iconSize())
|
self.setText(val)
|
||||||
p.fill(col)
|
p = QPixmap(self.iconSize())
|
||||||
self.setIcon(QIcon(p))
|
p.fill(col)
|
||||||
else:
|
self.setIcon(QIcon(p))
|
||||||
self._color = None
|
else:
|
||||||
self.setText(self.choose_text)
|
self._color = None
|
||||||
self.setIcon(QIcon())
|
self.setText(self.choose_text)
|
||||||
if orig != col:
|
self.setIcon(QIcon())
|
||||||
self.color_changed.emit(self._color)
|
if orig != col:
|
||||||
return property(fget=fget, fset=fset)
|
self.color_changed.emit(self._color)
|
||||||
|
|
||||||
def choose_color(self):
|
def choose_color(self):
|
||||||
col = QColorDialog.getColor(QColor(self._color or Qt.white), self, _('Choose a color'))
|
col = QColorDialog.getColor(QColor(self._color or Qt.white), self, _('Choose a color'))
|
||||||
|
@ -827,13 +827,10 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
|||||||
# _lock_file = None
|
# _lock_file = None
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def user_version(self):
|
def user_version(self):
|
||||||
doc = 'The user version of this database'
|
'The user version of this database'
|
||||||
|
return self.conn.get('pragma user_version;', all=False)
|
||||||
def fget(self):
|
|
||||||
return self.conn.get('pragma user_version;', all=False)
|
|
||||||
return property(doc=doc, fget=fget)
|
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return not self.conn.get('SELECT id FROM books LIMIT 1', all=False)
|
return not self.conn.get('SELECT id FROM books LIMIT 1', all=False)
|
||||||
|
@ -75,43 +75,36 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
PATH_LIMIT = 40 if 'win32' in sys.platform else 100
|
PATH_LIMIT = 40 if 'win32' in sys.platform else 100
|
||||||
WINDOWS_LIBRARY_PATH_LIMIT = 75
|
WINDOWS_LIBRARY_PATH_LIMIT = 75
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def user_version(self):
|
def user_version(self):
|
||||||
doc = 'The user version of this database'
|
'The user version of this database'
|
||||||
|
return self.conn.get('pragma user_version;', all=False)
|
||||||
|
|
||||||
def fget(self):
|
@user_version.setter
|
||||||
return self.conn.get('pragma user_version;', all=False)
|
def user_version(self, val):
|
||||||
|
self.conn.execute('pragma user_version=%d'%int(val))
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
def fset(self, val):
|
@property
|
||||||
self.conn.execute('pragma user_version=%d'%int(val))
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
return property(doc=doc, fget=fget, fset=fset)
|
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def library_id(self):
|
def library_id(self):
|
||||||
doc = ('The UUID for this library. As long as the user only operates'
|
'''The UUID for this library. As long as the user only operates on libraries with calibre, it will be unique'''
|
||||||
' on libraries with calibre, it will be unique')
|
if self._library_id_ is None:
|
||||||
|
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
||||||
|
if ans is None:
|
||||||
|
ans = str(uuid.uuid4())
|
||||||
|
self.library_id = ans
|
||||||
|
else:
|
||||||
|
self._library_id_ = ans
|
||||||
|
return self._library_id_
|
||||||
|
|
||||||
def fget(self):
|
@library_id.setter
|
||||||
if self._library_id_ is None:
|
def library_id(self, val):
|
||||||
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
self._library_id_ = unicode_type(val)
|
||||||
if ans is None:
|
self.conn.executescript('''
|
||||||
ans = str(uuid.uuid4())
|
DELETE FROM library_id;
|
||||||
self.library_id = ans
|
INSERT INTO library_id (uuid) VALUES ("%s");
|
||||||
else:
|
'''%self._library_id_)
|
||||||
self._library_id_ = ans
|
self.conn.commit()
|
||||||
return self._library_id_
|
|
||||||
|
|
||||||
def fset(self, val):
|
|
||||||
self._library_id_ = unicode_type(val)
|
|
||||||
self.conn.executescript('''
|
|
||||||
DELETE FROM library_id;
|
|
||||||
INSERT INTO library_id (uuid) VALUES ("%s");
|
|
||||||
'''%self._library_id_)
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
return property(doc=doc, fget=fget, fset=fset)
|
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
if iswindows and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259:
|
if iswindows and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259:
|
||||||
|
@ -57,47 +57,43 @@ class Image(object):
|
|||||||
def to_qimage(self):
|
def to_qimage(self):
|
||||||
return clone_image(self.img)
|
return clone_image(self.img)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
def fget(self):
|
if len(self.img.colorTable()) > 0:
|
||||||
if len(self.img.colorTable()) > 0:
|
return 'PaletteType'
|
||||||
return 'PaletteType'
|
return 'TrueColorType'
|
||||||
return 'TrueColorType'
|
|
||||||
|
|
||||||
def fset(self, t):
|
@type.setter
|
||||||
if t == 'GrayscaleType':
|
def type(self, t):
|
||||||
self.img = grayscale_image(self.img)
|
if t == 'GrayscaleType':
|
||||||
elif t == 'PaletteType':
|
self.img = grayscale_image(self.img)
|
||||||
self.img = quantize_image(self.img)
|
elif t == 'PaletteType':
|
||||||
return property(fget=fget, fset=fset)
|
self.img = quantize_image(self.img)
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def format(self):
|
def format(self):
|
||||||
def fget(self):
|
return self.write_format or self.read_format
|
||||||
return self.write_format or self.read_format
|
|
||||||
|
|
||||||
def fset(self, val):
|
@format.setter
|
||||||
self.write_format = val
|
def format(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self.write_format = val
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def colorspace(self):
|
def colorspace(self):
|
||||||
def fget(self):
|
return 'RGBColorspace'
|
||||||
return 'RGBColorspace'
|
|
||||||
|
|
||||||
def fset(self, val):
|
@colorspace.setter
|
||||||
raise NotImplementedError('Changing image colorspace is not supported')
|
def colorspace(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
raise NotImplementedError('Changing image colorspace is not supported')
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
def fget(self):
|
return self.img.width(), self.img.height()
|
||||||
return self.img.width(), self.img.height()
|
|
||||||
|
|
||||||
def fset(self, val):
|
@size.setter
|
||||||
w, h = val[:2]
|
def size(self, val):
|
||||||
self.img = resize_image(self.img, w, h)
|
w, h = val[:2]
|
||||||
return property(fget=fget, fset=fset)
|
self.img = resize_image(self.img, w, h)
|
||||||
|
|
||||||
def save(self, path, format=None):
|
def save(self, path, format=None):
|
||||||
if format is None:
|
if format is None:
|
||||||
|
@ -57,32 +57,29 @@ class Article(object):
|
|||||||
self.localtime = self.utctime.astimezone(local_tz)
|
self.localtime = self.utctime.astimezone(local_tz)
|
||||||
self._formatted_date = None
|
self._formatted_date = None
|
||||||
|
|
||||||
@dynamic_property
|
@property
|
||||||
def formatted_date(self):
|
def formatted_date(self):
|
||||||
|
|
||||||
def fget(self):
|
if self._formatted_date is None:
|
||||||
if self._formatted_date is None:
|
self._formatted_date = strftime(" [%a, %d %b %H:%M]",
|
||||||
self._formatted_date = strftime(" [%a, %d %b %H:%M]",
|
t=self.localtime.timetuple())
|
||||||
t=self.localtime.timetuple())
|
return self._formatted_date
|
||||||
return self._formatted_date
|
|
||||||
|
|
||||||
def fset(self, val):
|
@formatted_date.setter
|
||||||
if isinstance(val, unicode_type):
|
def formatted_date(self, val):
|
||||||
self._formatted_date = val
|
if isinstance(val, unicode_type):
|
||||||
|
self._formatted_date = val
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
@property
|
||||||
|
|
||||||
@dynamic_property
|
|
||||||
def title(self):
|
def title(self):
|
||||||
def fget(self):
|
t = self._title
|
||||||
t = self._title
|
if not isinstance(t, unicode_type) and hasattr(t, 'decode'):
|
||||||
if not isinstance(t, unicode_type) and hasattr(t, 'decode'):
|
t = t.decode('utf-8', 'replace')
|
||||||
t = t.decode('utf-8', 'replace')
|
return t
|
||||||
return t
|
|
||||||
|
|
||||||
def fset(self, val):
|
@title.setter
|
||||||
self._title = clean_ascii_chars(val)
|
def title(self, val):
|
||||||
return property(fget=fget, fset=fset)
|
self._title = clean_ascii_chars(val)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return \
|
return \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user