forked from openlp/openlp
Merge with upstream
This commit is contained in:
commit
44c4febd29
@ -137,7 +137,7 @@ def image_to_byte(image):
|
|||||||
# convert to base64 encoding so does not get missed!
|
# convert to base64 encoding so does not get missed!
|
||||||
return byte_array.toBase64()
|
return byte_array.toBase64()
|
||||||
|
|
||||||
def resize_image(image_path, width, height, background=QtCore.Qt.black):
|
def resize_image(image_path, width, height, background):
|
||||||
"""
|
"""
|
||||||
Resize an image to fit on the current screen.
|
Resize an image to fit on the current screen.
|
||||||
|
|
||||||
|
@ -31,11 +31,13 @@ import logging
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
from sqlalchemy import create_engine, MetaData
|
from sqlalchemy import Table, MetaData, Column, types, create_engine
|
||||||
from sqlalchemy.exc import InvalidRequestError
|
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
||||||
from sqlalchemy.pool import NullPool
|
from sqlalchemy.pool import NullPool
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation, delete_file
|
from openlp.core.utils import AppLocation, delete_file
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -59,6 +61,64 @@ def init_db(url, auto_flush=True, auto_commit=False):
|
|||||||
autocommit=auto_commit, bind=engine))
|
autocommit=auto_commit, bind=engine))
|
||||||
return session, metadata
|
return session, metadata
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_db(url, upgrade):
|
||||||
|
"""
|
||||||
|
Upgrade a database.
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The url of the database to upgrade.
|
||||||
|
|
||||||
|
``upgrade``
|
||||||
|
The python module that contains the upgrade instructions.
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
|
class Metadata(BaseModel):
|
||||||
|
"""
|
||||||
|
Provides a class for the metadata table.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
load_changes = True
|
||||||
|
try:
|
||||||
|
tables = upgrade.upgrade_setup(metadata)
|
||||||
|
except SQLAlchemyError, DBAPIError:
|
||||||
|
load_changes = False
|
||||||
|
metadata_table = Table(u'metadata', metadata,
|
||||||
|
Column(u'key', types.Unicode(64), primary_key=True),
|
||||||
|
Column(u'value', types.UnicodeText(), default=None)
|
||||||
|
)
|
||||||
|
metadata_table.create(checkfirst=True)
|
||||||
|
mapper(Metadata, metadata_table)
|
||||||
|
version_meta = session.query(Metadata).get(u'version')
|
||||||
|
if version_meta is None:
|
||||||
|
version_meta = Metadata.populate(key=u'version', value=u'0')
|
||||||
|
version = 0
|
||||||
|
else:
|
||||||
|
version = int(version_meta.value)
|
||||||
|
if version > upgrade.__version__:
|
||||||
|
return version, upgrade.__version__
|
||||||
|
version += 1
|
||||||
|
if load_changes:
|
||||||
|
while hasattr(upgrade, u'upgrade_%d' % version):
|
||||||
|
log.debug(u'Running upgrade_%d', version)
|
||||||
|
try:
|
||||||
|
getattr(upgrade, u'upgrade_%d' % version) \
|
||||||
|
(session, metadata, tables)
|
||||||
|
version_meta.value = unicode(version)
|
||||||
|
except SQLAlchemyError, DBAPIError:
|
||||||
|
log.exception(u'Could not run database upgrade script '
|
||||||
|
'"upgrade_%s", upgrade process has been halted.', version)
|
||||||
|
break
|
||||||
|
version += 1
|
||||||
|
else:
|
||||||
|
version_meta = Metadata.populate(key=u'version',
|
||||||
|
value=int(upgrade.__version__))
|
||||||
|
session.add(version_meta)
|
||||||
|
session.commit()
|
||||||
|
return int(version_meta.value), upgrade.__version__
|
||||||
|
|
||||||
|
|
||||||
def delete_database(plugin_name, db_file_name=None):
|
def delete_database(plugin_name, db_file_name=None):
|
||||||
"""
|
"""
|
||||||
Remove a database file from the system.
|
Remove a database file from the system.
|
||||||
@ -79,6 +139,7 @@ def delete_database(plugin_name, db_file_name=None):
|
|||||||
AppLocation.get_section_data_path(plugin_name), plugin_name)
|
AppLocation.get_section_data_path(plugin_name), plugin_name)
|
||||||
return delete_file(db_file_path)
|
return delete_file(db_file_path)
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(object):
|
class BaseModel(object):
|
||||||
"""
|
"""
|
||||||
BaseModel provides a base object with a set of generic functions
|
BaseModel provides a base object with a set of generic functions
|
||||||
@ -93,12 +154,12 @@ class BaseModel(object):
|
|||||||
instance.__setattr__(key, value)
|
instance.__setattr__(key, value)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
"""
|
"""
|
||||||
Provide generic object persistence management
|
Provide generic object persistence management
|
||||||
"""
|
"""
|
||||||
def __init__(self, plugin_name, init_schema, db_file_name=None):
|
def __init__(self, plugin_name, init_schema, db_file_name=None,
|
||||||
|
upgrade_mod=None):
|
||||||
"""
|
"""
|
||||||
Runs the initialisation process that includes creating the connection
|
Runs the initialisation process that includes creating the connection
|
||||||
to the database and the tables if they don't exist.
|
to the database and the tables if they don't exist.
|
||||||
@ -109,6 +170,9 @@ class Manager(object):
|
|||||||
``init_schema``
|
``init_schema``
|
||||||
The init_schema function for this database
|
The init_schema function for this database
|
||||||
|
|
||||||
|
``upgrade_schema``
|
||||||
|
The upgrade_schema function for this database
|
||||||
|
|
||||||
``db_file_name``
|
``db_file_name``
|
||||||
The file name to use for this database. Defaults to None resulting
|
The file name to use for this database. Defaults to None resulting
|
||||||
in the plugin_name being used.
|
in the plugin_name being used.
|
||||||
@ -134,7 +198,27 @@ class Manager(object):
|
|||||||
unicode(settings.value(u'db hostname').toString()),
|
unicode(settings.value(u'db hostname').toString()),
|
||||||
unicode(settings.value(u'db database').toString()))
|
unicode(settings.value(u'db database').toString()))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
self.session = init_schema(self.db_url)
|
if upgrade_mod:
|
||||||
|
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
|
||||||
|
if db_ver > up_ver:
|
||||||
|
critical_error_message_box(
|
||||||
|
translate('OpenLP.Manager', 'Database Error'),
|
||||||
|
unicode(translate('OpenLP.Manager', 'The database being '
|
||||||
|
'loaded was created in a more recent version of '
|
||||||
|
'OpenLP. The database is version %d, while OpenLP '
|
||||||
|
'expects version %d. The database will not be loaded.'
|
||||||
|
'\n\nDatabase: %s')) % \
|
||||||
|
(db_ver, up_ver, self.db_url)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
self.session = init_schema(self.db_url)
|
||||||
|
except:
|
||||||
|
critical_error_message_box(
|
||||||
|
translate('OpenLP.Manager', 'Database Error'),
|
||||||
|
unicode(translate('OpenLP.Manager', 'OpenLP cannot load your '
|
||||||
|
'database.\n\nDatabase: %s')) % self.db_url
|
||||||
|
)
|
||||||
|
|
||||||
def save_object(self, object_instance, commit=True):
|
def save_object(self, object_instance, commit=True):
|
||||||
"""
|
"""
|
||||||
@ -223,7 +307,9 @@ class Manager(object):
|
|||||||
query = self.session.query(object_class)
|
query = self.session.query(object_class)
|
||||||
if filter_clause is not None:
|
if filter_clause is not None:
|
||||||
query = query.filter(filter_clause)
|
query = query.filter(filter_clause)
|
||||||
if order_by_ref is not None:
|
if isinstance(order_by_ref, list):
|
||||||
|
return query.order_by(*order_by_ref).all()
|
||||||
|
elif order_by_ref is not None:
|
||||||
return query.order_by(order_by_ref).all()
|
return query.order_by(order_by_ref).all()
|
||||||
return query.all()
|
return query.all()
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ import Queue
|
|||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import resize_image, image_to_byte
|
from openlp.core.lib import resize_image, image_to_byte, Receiver
|
||||||
from openlp.core.ui import ScreenList
|
from openlp.core.ui import ScreenList
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -100,12 +100,14 @@ class Image(object):
|
|||||||
variables ``image`` and ``image_bytes`` to ``None`` and add the image object
|
variables ``image`` and ``image_bytes`` to ``None`` and add the image object
|
||||||
to the queue of images to process.
|
to the queue of images to process.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name='', path=''):
|
def __init__(self, name, path, source, background):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.path = path
|
self.path = path
|
||||||
self.image = None
|
self.image = None
|
||||||
self.image_bytes = None
|
self.image_bytes = None
|
||||||
self.priority = Priority.Normal
|
self.priority = Priority.Normal
|
||||||
|
self.source = source
|
||||||
|
self.background = background
|
||||||
|
|
||||||
|
|
||||||
class PriorityQueue(Queue.PriorityQueue):
|
class PriorityQueue(Queue.PriorityQueue):
|
||||||
@ -151,6 +153,8 @@ class ImageManager(QtCore.QObject):
|
|||||||
self._cache = {}
|
self._cache = {}
|
||||||
self._imageThread = ImageThread(self)
|
self._imageThread = ImageThread(self)
|
||||||
self._conversion_queue = PriorityQueue()
|
self._conversion_queue = PriorityQueue()
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'config_updated'), self.process_updates)
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
"""
|
"""
|
||||||
@ -162,12 +166,42 @@ class ImageManager(QtCore.QObject):
|
|||||||
self.height = current_screen[u'size'].height()
|
self.height = current_screen[u'size'].height()
|
||||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
# stream to None.
|
# stream to None.
|
||||||
self._conversion_queue = PriorityQueue()
|
|
||||||
for key, image in self._cache.iteritems():
|
for key, image in self._cache.iteritems():
|
||||||
image.priority = Priority.Normal
|
self._reset_image(image)
|
||||||
image.image = None
|
|
||||||
image.image_bytes = None
|
def update_images(self, image_type, background):
|
||||||
self._conversion_queue.put((image.priority, image))
|
"""
|
||||||
|
Border has changed so update all the images affected.
|
||||||
|
"""
|
||||||
|
log.debug(u'update_images')
|
||||||
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
|
# stream to None.
|
||||||
|
for key, image in self._cache.iteritems():
|
||||||
|
if image.source == image_type:
|
||||||
|
image.background = background
|
||||||
|
self._reset_image(image)
|
||||||
|
|
||||||
|
def update_image(self, name, image_type, background):
|
||||||
|
"""
|
||||||
|
Border has changed so update the image affected.
|
||||||
|
"""
|
||||||
|
log.debug(u'update_images')
|
||||||
|
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||||
|
# stream to None.
|
||||||
|
for key, image in self._cache.iteritems():
|
||||||
|
if image.source == image_type and image.name == name:
|
||||||
|
image.background = background
|
||||||
|
self._reset_image(image)
|
||||||
|
|
||||||
|
def _reset_image(self, image):
|
||||||
|
image.image = None
|
||||||
|
image.image_bytes = None
|
||||||
|
self._conversion_queue.modify_priority(image, Priority.Normal)
|
||||||
|
|
||||||
|
def process_updates(self):
|
||||||
|
"""
|
||||||
|
Flush the queue to updated any data to update
|
||||||
|
"""
|
||||||
# We want only one thread.
|
# We want only one thread.
|
||||||
if not self._imageThread.isRunning():
|
if not self._imageThread.isRunning():
|
||||||
self._imageThread.start()
|
self._imageThread.start()
|
||||||
@ -215,13 +249,13 @@ class ImageManager(QtCore.QObject):
|
|||||||
self._conversion_queue.remove(self._cache[name])
|
self._conversion_queue.remove(self._cache[name])
|
||||||
del self._cache[name]
|
del self._cache[name]
|
||||||
|
|
||||||
def add_image(self, name, path):
|
def add_image(self, name, path, source, background):
|
||||||
"""
|
"""
|
||||||
Add image to cache if it is not already there.
|
Add image to cache if it is not already there.
|
||||||
"""
|
"""
|
||||||
log.debug(u'add_image %s:%s' % (name, path))
|
log.debug(u'add_image %s:%s' % (name, path))
|
||||||
if not name in self._cache:
|
if not name in self._cache:
|
||||||
image = Image(name, path)
|
image = Image(name, path, source, background)
|
||||||
self._cache[name] = image
|
self._cache[name] = image
|
||||||
self._conversion_queue.put((image.priority, image))
|
self._conversion_queue.put((image.priority, image))
|
||||||
else:
|
else:
|
||||||
@ -247,7 +281,8 @@ class ImageManager(QtCore.QObject):
|
|||||||
image = self._conversion_queue.get()[1]
|
image = self._conversion_queue.get()[1]
|
||||||
# Generate the QImage for the image.
|
# Generate the QImage for the image.
|
||||||
if image.image is None:
|
if image.image is None:
|
||||||
image.image = resize_image(image.path, self.width, self.height)
|
image.image = resize_image(image.path, self.width, self.height,
|
||||||
|
image.background)
|
||||||
# Set the priority to Lowest and stop here as we need to process
|
# Set the priority to Lowest and stop here as we need to process
|
||||||
# more important images first.
|
# more important images first.
|
||||||
if image.priority == Priority.Normal:
|
if image.priority == Priority.Normal:
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtWebKit
|
from PyQt4 import QtGui, QtCore, QtWebKit
|
||||||
|
|
||||||
from openlp.core.lib import ServiceItem, expand_tags, \
|
from openlp.core.lib import ServiceItem, expand_tags, \
|
||||||
build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
|
build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
|
||||||
@ -166,7 +166,8 @@ class Renderer(object):
|
|||||||
# if No file do not update cache
|
# if No file do not update cache
|
||||||
if self.theme_data.background_filename:
|
if self.theme_data.background_filename:
|
||||||
self.imageManager.add_image(self.theme_data.theme_name,
|
self.imageManager.add_image(self.theme_data.theme_name,
|
||||||
self.theme_data.background_filename)
|
self.theme_data.background_filename, u'theme',
|
||||||
|
QtGui.QColor(self.theme_data.background_border_color))
|
||||||
return self._rect, self._rect_footer
|
return self._rect, self._rect_footer
|
||||||
|
|
||||||
def generate_preview(self, theme_data, force_page=False):
|
def generate_preview(self, theme_data, force_page=False):
|
||||||
@ -227,15 +228,56 @@ class Renderer(object):
|
|||||||
# Clean up line endings.
|
# Clean up line endings.
|
||||||
lines = self._lines_split(text)
|
lines = self._lines_split(text)
|
||||||
pages = self._paginate_slide(lines, line_end)
|
pages = self._paginate_slide(lines, line_end)
|
||||||
if len(pages) > 1:
|
# Songs and Custom
|
||||||
# Songs and Custom
|
if item.is_capable(ItemCapabilities.AllowsVirtualSplit) and \
|
||||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
len(pages) > 1 and u'[---]' in text:
|
||||||
# Do not forget the line breaks!
|
pages = []
|
||||||
slides = text.split(u'[---]')
|
while True:
|
||||||
pages = []
|
# Check if the first two potential virtual slides will fit
|
||||||
for slide in slides:
|
# (as a whole) on one slide.
|
||||||
lines = slide.strip(u'\n').split(u'\n')
|
html_text = expand_tags(
|
||||||
|
u'\n'.join(text.split(u'\n[---]\n', 2)[:-1]))
|
||||||
|
html_text = html_text.replace(u'\n', u'<br>')
|
||||||
|
if self._text_fits_on_slide(html_text):
|
||||||
|
# The first two virtual slides fit (as a whole) on one
|
||||||
|
# slide. Replace the occurrences of [---].
|
||||||
|
text = text.replace(u'\n[---]', u'', 2)
|
||||||
|
else:
|
||||||
|
# The first two virtual slides did not fit as a whole.
|
||||||
|
# Check if the first virtual slide will fit.
|
||||||
|
html_text = expand_tags(text.split(u'\n[---]\n', 1)[1])
|
||||||
|
html_text = html_text.replace(u'\n', u'<br>')
|
||||||
|
if self._text_fits_on_slide(html_text):
|
||||||
|
# The first virtual slide fits, so remove it.
|
||||||
|
text = text.replace(u'\n[---]', u'', 1)
|
||||||
|
else:
|
||||||
|
# The first virtual slide does not fit, which means
|
||||||
|
# we have to render the first virtual slide.
|
||||||
|
text_contains_break = u'[---]' in text
|
||||||
|
if text_contains_break:
|
||||||
|
html_text, text = text.split(u'\n[---]\n', 1)
|
||||||
|
else:
|
||||||
|
html_text = text
|
||||||
|
text = u''
|
||||||
|
lines = expand_tags(html_text)
|
||||||
|
lines = lines.strip(u'\n').split(u'\n')
|
||||||
|
slides = self._paginate_slide(lines, line_end)
|
||||||
|
if len(slides) > 1 and text:
|
||||||
|
# Add all slides apart from the last one the
|
||||||
|
# list.
|
||||||
|
pages.extend(slides[:-1])
|
||||||
|
if text_contains_break:
|
||||||
|
text = slides[-1] + u'\n[---]\n' + text
|
||||||
|
else:
|
||||||
|
text = slides[-1] + u'\n'+ text
|
||||||
|
text = text.replace(u'<br>', u'\n')
|
||||||
|
else:
|
||||||
|
pages.extend(slides)
|
||||||
|
if u'[---]' not in text:
|
||||||
|
lines = expand_tags(text)
|
||||||
|
lines = lines.strip(u'\n').split(u'\n')
|
||||||
pages.extend(self._paginate_slide(lines, line_end))
|
pages.extend(self._paginate_slide(lines, line_end))
|
||||||
|
break
|
||||||
new_pages = []
|
new_pages = []
|
||||||
for page in pages:
|
for page in pages:
|
||||||
while page.endswith(u'<br>'):
|
while page.endswith(u'<br>'):
|
||||||
@ -341,7 +383,7 @@ class Renderer(object):
|
|||||||
separator = u'<br>'
|
separator = u'<br>'
|
||||||
html_lines = map(expand_tags, lines)
|
html_lines = map(expand_tags, lines)
|
||||||
# Text too long so go to next page.
|
# Text too long so go to next page.
|
||||||
if self._text_fits_on_slide(separator.join(html_lines)):
|
if not self._text_fits_on_slide(separator.join(html_lines)):
|
||||||
html_text, previous_raw = self._binary_chop(formatted,
|
html_text, previous_raw = self._binary_chop(formatted,
|
||||||
previous_html, previous_raw, html_lines, lines, separator, u'')
|
previous_html, previous_raw, html_lines, lines, separator, u'')
|
||||||
else:
|
else:
|
||||||
@ -374,18 +416,18 @@ class Renderer(object):
|
|||||||
line = line.strip()
|
line = line.strip()
|
||||||
html_line = expand_tags(line)
|
html_line = expand_tags(line)
|
||||||
# Text too long so go to next page.
|
# Text too long so go to next page.
|
||||||
if self._text_fits_on_slide(previous_html + html_line):
|
if not self._text_fits_on_slide(previous_html + html_line):
|
||||||
# Check if there was a verse before the current one and append
|
# Check if there was a verse before the current one and append
|
||||||
# it, when it fits on the page.
|
# it, when it fits on the page.
|
||||||
if previous_html:
|
if previous_html:
|
||||||
if not self._text_fits_on_slide(previous_html):
|
if self._text_fits_on_slide(previous_html):
|
||||||
formatted.append(previous_raw)
|
formatted.append(previous_raw)
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
# Now check if the current verse will fit, if it does
|
# Now check if the current verse will fit, if it does
|
||||||
# not we have to start to process the verse word by
|
# not we have to start to process the verse word by
|
||||||
# word.
|
# word.
|
||||||
if not self._text_fits_on_slide(html_line):
|
if self._text_fits_on_slide(html_line):
|
||||||
previous_html = html_line + line_end
|
previous_html = html_line + line_end
|
||||||
previous_raw = line + line_end
|
previous_raw = line + line_end
|
||||||
continue
|
continue
|
||||||
@ -442,7 +484,7 @@ class Renderer(object):
|
|||||||
highest_index = len(html_list) - 1
|
highest_index = len(html_list) - 1
|
||||||
index = int(highest_index / 2)
|
index = int(highest_index / 2)
|
||||||
while True:
|
while True:
|
||||||
if self._text_fits_on_slide(
|
if not self._text_fits_on_slide(
|
||||||
previous_html + separator.join(html_list[:index + 1]).strip()):
|
previous_html + separator.join(html_list[:index + 1]).strip()):
|
||||||
# We know that it does not fit, so change/calculate the
|
# We know that it does not fit, so change/calculate the
|
||||||
# new index and highest_index accordingly.
|
# new index and highest_index accordingly.
|
||||||
@ -465,8 +507,8 @@ class Renderer(object):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
# Check if the remaining elements fit on the slide.
|
# Check if the remaining elements fit on the slide.
|
||||||
if not self._text_fits_on_slide(
|
if self._text_fits_on_slide(
|
||||||
separator.join(html_list[index + 1:]).strip()):
|
separator.join(html_list[index + 1:]).strip()):
|
||||||
previous_html = separator.join(
|
previous_html = separator.join(
|
||||||
html_list[index + 1:]).strip() + line_end
|
html_list[index + 1:]).strip() + line_end
|
||||||
previous_raw = separator.join(
|
previous_raw = separator.join(
|
||||||
@ -488,11 +530,11 @@ class Renderer(object):
|
|||||||
returned, otherwise ``False``.
|
returned, otherwise ``False``.
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text to check. It can contain HTML tags.
|
The text to check. It may contain HTML tags.
|
||||||
"""
|
"""
|
||||||
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
||||||
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||||
return self.web_frame.contentsSize().height() > self.page_height
|
return self.web_frame.contentsSize().height() <= self.page_height
|
||||||
|
|
||||||
def _words_split(self, line):
|
def _words_split(self, line):
|
||||||
"""
|
"""
|
||||||
|
@ -115,6 +115,7 @@ class ServiceItem(object):
|
|||||||
self.end_time = 0
|
self.end_time = 0
|
||||||
self.media_length = 0
|
self.media_length = 0
|
||||||
self.from_service = False
|
self.from_service = False
|
||||||
|
self.image_border = u'#000000'
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def _new_item(self):
|
def _new_item(self):
|
||||||
@ -195,7 +196,7 @@ class ServiceItem(object):
|
|||||||
self.foot_text = \
|
self.foot_text = \
|
||||||
u'<br>'.join([footer for footer in self.raw_footer if footer])
|
u'<br>'.join([footer for footer in self.raw_footer if footer])
|
||||||
|
|
||||||
def add_from_image(self, path, title):
|
def add_from_image(self, path, title, background=None):
|
||||||
"""
|
"""
|
||||||
Add an image slide to the service item.
|
Add an image slide to the service item.
|
||||||
|
|
||||||
@ -205,9 +206,12 @@ class ServiceItem(object):
|
|||||||
``title``
|
``title``
|
||||||
A title for the slide in the service item.
|
A title for the slide in the service item.
|
||||||
"""
|
"""
|
||||||
|
if background:
|
||||||
|
self.image_border = background
|
||||||
self.service_item_type = ServiceItemType.Image
|
self.service_item_type = ServiceItemType.Image
|
||||||
self._raw_frames.append({u'title': title, u'path': path})
|
self._raw_frames.append({u'title': title, u'path': path})
|
||||||
self.renderer.imageManager.add_image(title, path)
|
self.renderer.imageManager.add_image(title, path, u'image',
|
||||||
|
self.image_border)
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def add_from_text(self, title, raw_slide, verse_tag=None):
|
def add_from_text(self, title, raw_slide, verse_tag=None):
|
||||||
|
@ -44,6 +44,7 @@ BLANK_THEME_XML = \
|
|||||||
<name> </name>
|
<name> </name>
|
||||||
<background type="image">
|
<background type="image">
|
||||||
<filename></filename>
|
<filename></filename>
|
||||||
|
<borderColor>#000000</borderColor>
|
||||||
</background>
|
</background>
|
||||||
<background type="gradient">
|
<background type="gradient">
|
||||||
<startColor>#000000</startColor>
|
<startColor>#000000</startColor>
|
||||||
@ -282,7 +283,7 @@ class ThemeXML(object):
|
|||||||
# Create direction element
|
# Create direction element
|
||||||
self.child_element(background, u'direction', unicode(direction))
|
self.child_element(background, u'direction', unicode(direction))
|
||||||
|
|
||||||
def add_background_image(self, filename):
|
def add_background_image(self, filename, borderColor):
|
||||||
"""
|
"""
|
||||||
Add a image background.
|
Add a image background.
|
||||||
|
|
||||||
@ -294,6 +295,8 @@ class ThemeXML(object):
|
|||||||
self.theme.appendChild(background)
|
self.theme.appendChild(background)
|
||||||
# Create Filename element
|
# Create Filename element
|
||||||
self.child_element(background, u'filename', filename)
|
self.child_element(background, u'filename', filename)
|
||||||
|
# Create endColor element
|
||||||
|
self.child_element(background, u'borderColor', unicode(borderColor))
|
||||||
|
|
||||||
def add_font(self, name, color, size, override, fonttype=u'main',
|
def add_font(self, name, color, size, override, fonttype=u'main',
|
||||||
bold=u'False', italics=u'False', line_adjustment=0,
|
bold=u'False', italics=u'False', line_adjustment=0,
|
||||||
@ -597,7 +600,7 @@ class ThemeXML(object):
|
|||||||
self.background_direction)
|
self.background_direction)
|
||||||
else:
|
else:
|
||||||
filename = os.path.split(self.background_filename)[1]
|
filename = os.path.split(self.background_filename)[1]
|
||||||
self.add_background_image(filename)
|
self.add_background_image(filename, self.background_border_color)
|
||||||
self.add_font(self.font_main_name,
|
self.add_font(self.font_main_name,
|
||||||
self.font_main_color,
|
self.font_main_color,
|
||||||
self.font_main_size,
|
self.font_main_size,
|
||||||
|
@ -116,7 +116,7 @@ class Ui_AboutDialog(object):
|
|||||||
u'Scott "sguerrieri" Guerrieri',
|
u'Scott "sguerrieri" Guerrieri',
|
||||||
u'Matthias "matthub" Hub', u'Meinert "m2j" Jordan',
|
u'Matthias "matthub" Hub', u'Meinert "m2j" Jordan',
|
||||||
u'Armin "orangeshirt" K\xf6hler', u'Joshua "milleja46" Miller',
|
u'Armin "orangeshirt" K\xf6hler', u'Joshua "milleja46" Miller',
|
||||||
u'Stevan "StevanP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru',
|
u'Stevan "ElderP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru',
|
||||||
u'Christian "crichter" Richter', u'Philip "Phill" Ridout',
|
u'Christian "crichter" Richter', u'Philip "Phill" Ridout',
|
||||||
u'Simon "samscudder" Scudder', u'Jeffrey "whydoubt" Smith',
|
u'Simon "samscudder" Scudder', u'Jeffrey "whydoubt" Smith',
|
||||||
u'Maikel Stuivenberg', u'Frode "frodus" Woldsund']
|
u'Maikel Stuivenberg', u'Frode "frodus" Woldsund']
|
||||||
@ -125,7 +125,7 @@ class Ui_AboutDialog(object):
|
|||||||
packagers = ['Thomas "tabthorpe" Abthorpe (FreeBSD)',
|
packagers = ['Thomas "tabthorpe" Abthorpe (FreeBSD)',
|
||||||
u'Tim "TRB143" Bentley (Fedora)',
|
u'Tim "TRB143" Bentley (Fedora)',
|
||||||
u'Matthias "matthub" Hub (Mac OS X)',
|
u'Matthias "matthub" Hub (Mac OS X)',
|
||||||
u'Stevan "StevanP" Pettit (Windows)',
|
u'Stevan "ElderP" Pettit (Windows)',
|
||||||
u'Raoul "superfly" Snyman (Ubuntu)']
|
u'Raoul "superfly" Snyman (Ubuntu)']
|
||||||
translators = {
|
translators = {
|
||||||
u'af': [u'Johan "nuvolari" Mynhardt'],
|
u'af': [u'Johan "nuvolari" Mynhardt'],
|
||||||
|
@ -228,11 +228,11 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
shrinkItem.setVisible(False)
|
shrinkItem.setVisible(False)
|
||||||
self.setGeometry(self.screen[u'size'])
|
self.setGeometry(self.screen[u'size'])
|
||||||
|
|
||||||
def directImage(self, name, path):
|
def directImage(self, name, path, background):
|
||||||
"""
|
"""
|
||||||
API for replacement backgrounds so Images are added directly to cache
|
API for replacement backgrounds so Images are added directly to cache
|
||||||
"""
|
"""
|
||||||
self.imageManager.add_image(name, path)
|
self.imageManager.add_image(name, path, u'image', background)
|
||||||
if hasattr(self, u'serviceItem'):
|
if hasattr(self, u'serviceItem'):
|
||||||
self.override[u'image'] = name
|
self.override[u'image'] = name
|
||||||
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
||||||
|
@ -28,12 +28,15 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import shutil
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
||||||
PluginManager, Receiver, translate, ImageManager, PluginStatus
|
PluginManager, Receiver, translate, ImageManager, PluginStatus, \
|
||||||
|
SettingsManager
|
||||||
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||||
icon_action, shortcut_action
|
icon_action, shortcut_action
|
||||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
||||||
@ -213,7 +216,7 @@ class Ui_MainWindow(object):
|
|||||||
self.mediaManagerDock.isVisible(), UiStrings().View)
|
self.mediaManagerDock.isVisible(), UiStrings().View)
|
||||||
self.viewThemeManagerItem = shortcut_action(mainWindow,
|
self.viewThemeManagerItem = shortcut_action(mainWindow,
|
||||||
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
||||||
self.toggleThemeManager, u':/system/system_thememanager.png',
|
self.toggleThemeManager, u':/system/system_thememanager.png',
|
||||||
self.themeManagerDock.isVisible(), UiStrings().View)
|
self.themeManagerDock.isVisible(), UiStrings().View)
|
||||||
self.viewServiceManagerItem = shortcut_action(mainWindow,
|
self.viewServiceManagerItem = shortcut_action(mainWindow,
|
||||||
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
||||||
@ -283,6 +286,10 @@ class Ui_MainWindow(object):
|
|||||||
self.settingsConfigureItem = icon_action(mainWindow,
|
self.settingsConfigureItem = icon_action(mainWindow,
|
||||||
u'settingsConfigureItem', u':/system/system_settings.png',
|
u'settingsConfigureItem', u':/system/system_settings.png',
|
||||||
category=UiStrings().Settings)
|
category=UiStrings().Settings)
|
||||||
|
self.settingsImportItem = base_action(mainWindow,
|
||||||
|
u'settingsImportItem', category=UiStrings().Settings)
|
||||||
|
self.settingsExportItem = base_action(mainWindow,
|
||||||
|
u'settingsExportItem', category=UiStrings().Settings)
|
||||||
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
|
||||||
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
|
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
|
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
|
||||||
@ -300,15 +307,15 @@ class Ui_MainWindow(object):
|
|||||||
u':/system/system_online_help.png', category=UiStrings().Help)
|
u':/system/system_online_help.png', category=UiStrings().Help)
|
||||||
self.webSiteItem = base_action(
|
self.webSiteItem = base_action(
|
||||||
mainWindow, u'webSiteItem', category=UiStrings().Help)
|
mainWindow, u'webSiteItem', category=UiStrings().Help)
|
||||||
add_actions(self.fileImportMenu,
|
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
|
||||||
(self.importThemeItem, self.importLanguageItem))
|
self.importThemeItem, self.importLanguageItem))
|
||||||
add_actions(self.fileExportMenu,
|
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
|
||||||
(self.exportThemeItem, self.exportLanguageItem))
|
self.exportThemeItem, self.exportLanguageItem))
|
||||||
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
||||||
self.fileSaveItem, self.fileSaveAsItem, None,
|
self.fileSaveItem, self.fileSaveAsItem,
|
||||||
self.recentFilesMenu.menuAction(), None, self.printServiceOrderItem,
|
self.recentFilesMenu.menuAction(), None,
|
||||||
None, self.fileImportMenu.menuAction(),
|
self.fileImportMenu.menuAction(), self.fileExportMenu.menuAction(),
|
||||||
self.fileExportMenu.menuAction(), self.fileExitItem))
|
None, self.printServiceOrderItem, self.fileExitItem))
|
||||||
add_actions(self.viewModeMenu, (self.modeDefaultItem,
|
add_actions(self.viewModeMenu, (self.modeDefaultItem,
|
||||||
self.modeSetupItem, self.modeLiveItem))
|
self.modeSetupItem, self.modeLiveItem))
|
||||||
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
|
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
|
||||||
@ -356,6 +363,7 @@ class Ui_MainWindow(object):
|
|||||||
self.importLanguageItem.setVisible(False)
|
self.importLanguageItem.setVisible(False)
|
||||||
self.exportLanguageItem.setVisible(False)
|
self.exportLanguageItem.setVisible(False)
|
||||||
self.setLockPanel(panelLocked)
|
self.setLockPanel(panelLocked)
|
||||||
|
self.settingsImported = False
|
||||||
|
|
||||||
def retranslateUi(self, mainWindow):
|
def retranslateUi(self, mainWindow):
|
||||||
"""
|
"""
|
||||||
@ -416,9 +424,18 @@ class Ui_MainWindow(object):
|
|||||||
self.settingsShortcutsItem.setText(
|
self.settingsShortcutsItem.setText(
|
||||||
translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
|
translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
|
||||||
self.formattingTagItem.setText(
|
self.formattingTagItem.setText(
|
||||||
translate('OpenLP.MainWindow', '&Configure Formatting Tags...'))
|
translate('OpenLP.MainWindow', 'Configure &Formatting Tags...'))
|
||||||
self.settingsConfigureItem.setText(
|
self.settingsConfigureItem.setText(
|
||||||
translate('OpenLP.MainWindow', '&Configure OpenLP...'))
|
translate('OpenLP.MainWindow', '&Configure OpenLP...'))
|
||||||
|
self.settingsExportItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||||
|
'Export OpenLP settings to a specified *.config file'))
|
||||||
|
self.settingsExportItem.setText(
|
||||||
|
translate('OpenLP.MainWindow', 'Settings'))
|
||||||
|
self.settingsImportItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||||
|
'Import OpenLP settings from a specified *.config file previously '
|
||||||
|
'exported on this or another machine'))
|
||||||
|
self.settingsImportItem.setText(
|
||||||
|
translate('OpenLP.MainWindow', 'Settings'))
|
||||||
self.viewMediaManagerItem.setText(
|
self.viewMediaManagerItem.setText(
|
||||||
translate('OpenLP.MainWindow', '&Media Manager'))
|
translate('OpenLP.MainWindow', '&Media Manager'))
|
||||||
self.viewMediaManagerItem.setToolTip(
|
self.viewMediaManagerItem.setToolTip(
|
||||||
@ -522,8 +539,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
# (not for use by plugins)
|
# (not for use by plugins)
|
||||||
self.uiSettingsSection = u'user interface'
|
self.uiSettingsSection = u'user interface'
|
||||||
self.generalSettingsSection = u'general'
|
self.generalSettingsSection = u'general'
|
||||||
self.serviceSettingsSection = u'servicemanager'
|
self.advancedlSettingsSection = u'advanced'
|
||||||
|
self.servicemanagerSettingsSection = u'servicemanager'
|
||||||
self.songsSettingsSection = u'songs'
|
self.songsSettingsSection = u'songs'
|
||||||
|
self.themesSettingsSection = u'themes'
|
||||||
|
self.displayTagsSection = u'displayTags'
|
||||||
|
self.headerSection = u'SettingsImport'
|
||||||
self.serviceNotSaved = False
|
self.serviceNotSaved = False
|
||||||
self.aboutForm = AboutForm(self)
|
self.aboutForm = AboutForm(self)
|
||||||
self.settingsForm = SettingsForm(self, self)
|
self.settingsForm = SettingsForm(self, self)
|
||||||
@ -572,6 +593,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
||||||
QtCore.QObject.connect(self.settingsShortcutsItem,
|
QtCore.QObject.connect(self.settingsShortcutsItem,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked)
|
||||||
|
QtCore.QObject.connect(self.settingsImportItem,
|
||||||
|
QtCore.SIGNAL(u'triggered()'), self.onSettingsImportItemClicked)
|
||||||
|
QtCore.QObject.connect(self.settingsExportItem,
|
||||||
|
QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked)
|
||||||
# i18n set signals for languages
|
# i18n set signals for languages
|
||||||
self.languageGroup.triggered.connect(LanguageManager.set_language)
|
self.languageGroup.triggered.connect(LanguageManager.set_language)
|
||||||
QtCore.QObject.connect(self.modeDefaultItem,
|
QtCore.QObject.connect(self.modeDefaultItem,
|
||||||
@ -726,11 +751,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
plugin.firstTime()
|
plugin.firstTime()
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
|
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
|
||||||
if not os.path.exists(temp_dir):
|
shutil.rmtree(temp_dir, True)
|
||||||
return
|
|
||||||
for filename in os.listdir(temp_dir):
|
|
||||||
delete_file(os.path.join(temp_dir, filename))
|
|
||||||
os.removedirs(temp_dir)
|
|
||||||
|
|
||||||
def onFirstTimeWizardClicked(self):
|
def onFirstTimeWizardClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -871,6 +892,172 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
if self.shortcutForm.exec_():
|
if self.shortcutForm.exec_():
|
||||||
self.shortcutForm.save()
|
self.shortcutForm.save()
|
||||||
|
|
||||||
|
def onSettingsImportItemClicked(self):
|
||||||
|
"""
|
||||||
|
Import settings from an export INI file
|
||||||
|
"""
|
||||||
|
answer = QtGui.QMessageBox.critical(self,
|
||||||
|
translate('OpenLP.MainWindow', 'Import settings?'),
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'Are you sure you want to import settings?\n\n'
|
||||||
|
'Importing settings will make permanent changes to your current '
|
||||||
|
'OpenLP configuration.\n\n'
|
||||||
|
'Importing incorrect settings may cause erratic behaviour or '
|
||||||
|
'OpenLP to terminate abnormally.'),
|
||||||
|
QtGui.QMessageBox.StandardButtons(
|
||||||
|
QtGui.QMessageBox.Yes |
|
||||||
|
QtGui.QMessageBox.No),
|
||||||
|
QtGui.QMessageBox.No)
|
||||||
|
if answer == QtGui.QMessageBox.No:
|
||||||
|
return
|
||||||
|
importFileName = unicode(QtGui.QFileDialog.getOpenFileName(self,
|
||||||
|
translate('OpenLP.MainWindow', 'Open File'),
|
||||||
|
'',
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'OpenLP Export Settings Files (*.conf)')))
|
||||||
|
if not importFileName:
|
||||||
|
return
|
||||||
|
settingSections = []
|
||||||
|
# Add main sections.
|
||||||
|
settingSections.extend([self.generalSettingsSection])
|
||||||
|
settingSections.extend([self.advancedlSettingsSection])
|
||||||
|
settingSections.extend([self.uiSettingsSection])
|
||||||
|
settingSections.extend([self.servicemanagerSettingsSection])
|
||||||
|
settingSections.extend([self.themesSettingsSection])
|
||||||
|
settingSections.extend([self.displayTagsSection])
|
||||||
|
settingSections.extend([self.headerSection])
|
||||||
|
# Add plugin sections.
|
||||||
|
for plugin in self.pluginManager.plugins:
|
||||||
|
settingSections.extend([plugin.name])
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
importSettings = QtCore.QSettings(importFileName,
|
||||||
|
QtCore.QSettings.IniFormat)
|
||||||
|
importKeys = importSettings.allKeys()
|
||||||
|
for sectionKey in importKeys:
|
||||||
|
# We need to handle the really bad files.
|
||||||
|
try:
|
||||||
|
section, key = sectionKey.split(u'/')
|
||||||
|
except ValueError:
|
||||||
|
section = u'unknown'
|
||||||
|
key = u''
|
||||||
|
# Switch General back to lowercase.
|
||||||
|
if section == u'General':
|
||||||
|
section = u'general'
|
||||||
|
sectionKey = section + "/" + key
|
||||||
|
# Make sure it's a valid section for us.
|
||||||
|
if not section in settingSections:
|
||||||
|
QtGui.QMessageBox.critical(self,
|
||||||
|
translate('OpenLP.MainWindow', 'Import settings'),
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'The file you selected does appear to be a valid OpenLP '
|
||||||
|
'settings file.\n\n'
|
||||||
|
'Section [%s] is not valid \n\n'
|
||||||
|
'Processing has terminated and no changed have been made.'
|
||||||
|
% section),
|
||||||
|
QtGui.QMessageBox.StandardButtons(
|
||||||
|
QtGui.QMessageBox.Ok))
|
||||||
|
return
|
||||||
|
# We have a good file, import it.
|
||||||
|
for sectionKey in importKeys:
|
||||||
|
value = importSettings.value(sectionKey)
|
||||||
|
settings.setValue(u'%s' % (sectionKey) ,
|
||||||
|
QtCore.QVariant(value))
|
||||||
|
now = datetime.now()
|
||||||
|
settings.beginGroup(self.headerSection)
|
||||||
|
settings.setValue( u'file_imported' , QtCore.QVariant(importFileName))
|
||||||
|
settings.setValue(u'file_date_imported',
|
||||||
|
now.strftime("%Y-%m-%d %H:%M"))
|
||||||
|
settings.endGroup()
|
||||||
|
settings.sync()
|
||||||
|
# We must do an immediate restart or current configuration will
|
||||||
|
# overwrite what was just imported when application terminates
|
||||||
|
# normally. We need to exit without saving configuration.
|
||||||
|
QtGui.QMessageBox.information(self,
|
||||||
|
translate('OpenLP.MainWindow', 'Import settings'),
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'OpenLP will now close. Imported settings will '
|
||||||
|
'be applied the next time you start OpenLP.'),
|
||||||
|
QtGui.QMessageBox.StandardButtons(
|
||||||
|
QtGui.QMessageBox.Ok))
|
||||||
|
self.settingsImported = True
|
||||||
|
self.cleanUp()
|
||||||
|
QtCore.QCoreApplication.exit()
|
||||||
|
|
||||||
|
def onSettingsExportItemClicked(self, exportFileName=None):
|
||||||
|
"""
|
||||||
|
Export settings to an INI file
|
||||||
|
"""
|
||||||
|
if not exportFileName:
|
||||||
|
exportFileName = unicode(QtGui.QFileDialog.getSaveFileName(self,
|
||||||
|
translate('OpenLP.MainWindow', 'Export Settings File'), '',
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'OpenLP Export Settings File (*.conf)')))
|
||||||
|
if not exportFileName:
|
||||||
|
return
|
||||||
|
# Make sure it's an .ini file.
|
||||||
|
if not exportFileName.endswith(u'conf'):
|
||||||
|
exportFileName = exportFileName + u'.conf'
|
||||||
|
temp_file = os.path.join(unicode(gettempdir()),
|
||||||
|
u'openlp', u'exportIni.tmp')
|
||||||
|
self.saveSettings()
|
||||||
|
settingSections = []
|
||||||
|
# Add main sections.
|
||||||
|
settingSections.extend([self.generalSettingsSection])
|
||||||
|
settingSections.extend([self.advancedlSettingsSection])
|
||||||
|
settingSections.extend([self.uiSettingsSection])
|
||||||
|
settingSections.extend([self.servicemanagerSettingsSection])
|
||||||
|
settingSections.extend([self.themesSettingsSection])
|
||||||
|
settingSections.extend([self.displayTagsSection])
|
||||||
|
# Add plugin sections.
|
||||||
|
for plugin in self.pluginManager.plugins:
|
||||||
|
settingSections.extend([plugin.name])
|
||||||
|
# Delete old files if found.
|
||||||
|
if os.path.exists(temp_file):
|
||||||
|
os.remove(temp_file)
|
||||||
|
if os.path.exists(exportFileName):
|
||||||
|
os.remove(exportFileName)
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
settings.remove(self.headerSection)
|
||||||
|
# Get the settings.
|
||||||
|
keys = settings.allKeys()
|
||||||
|
exportSettings = QtCore.QSettings(temp_file,
|
||||||
|
QtCore.QSettings.IniFormat)
|
||||||
|
# Add a header section.
|
||||||
|
# This is to insure it's our ini file for import.
|
||||||
|
now = datetime.now()
|
||||||
|
applicationVersion = get_application_version()
|
||||||
|
# Write INI format using Qsettings.
|
||||||
|
# Write our header.
|
||||||
|
exportSettings.beginGroup(self.headerSection)
|
||||||
|
exportSettings.setValue(u'Make_Changes', u'At_Own_RISK')
|
||||||
|
exportSettings.setValue(u'type', u'OpenLP_settings_export')
|
||||||
|
exportSettings.setValue(u'file_date_created',
|
||||||
|
now.strftime("%Y-%m-%d %H:%M"))
|
||||||
|
exportSettings.setValue(u'version', applicationVersion[u'full'])
|
||||||
|
exportSettings.endGroup()
|
||||||
|
# Write all the sections and keys.
|
||||||
|
for sectionKey in keys:
|
||||||
|
section, key = sectionKey.split(u'/')
|
||||||
|
keyValue = settings.value(sectionKey)
|
||||||
|
sectionKey = section + u"/" + key
|
||||||
|
# Change the service section to servicemanager.
|
||||||
|
if section == u'service':
|
||||||
|
sectionKey = u'servicemanager/' + key
|
||||||
|
exportSettings.setValue(sectionKey, keyValue)
|
||||||
|
exportSettings.sync()
|
||||||
|
# Temp INI file has been written. Blanks in keys are now '%20'.
|
||||||
|
# Read the temp file and output the user's INI file with blanks to
|
||||||
|
# make it more readable.
|
||||||
|
tempIni = open(temp_file, u'r')
|
||||||
|
exportIni = open(exportFileName, u'w')
|
||||||
|
for fileRecord in tempIni:
|
||||||
|
fileRecord = fileRecord.replace(u'%20', u' ')
|
||||||
|
exportIni.write(fileRecord)
|
||||||
|
tempIni.close()
|
||||||
|
exportIni.close()
|
||||||
|
os.remove(temp_file)
|
||||||
|
return
|
||||||
|
|
||||||
def onModeDefaultItemClicked(self):
|
def onModeDefaultItemClicked(self):
|
||||||
"""
|
"""
|
||||||
Put OpenLP into "Default" view mode.
|
Put OpenLP into "Default" view mode.
|
||||||
@ -923,6 +1110,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
Hook to close the main window and display windows on exit
|
Hook to close the main window and display windows on exit
|
||||||
"""
|
"""
|
||||||
|
# If we just did a settings import, close without saving changes.
|
||||||
|
if self.settingsImported:
|
||||||
|
event.accept()
|
||||||
if self.serviceManagerContents.isModified():
|
if self.serviceManagerContents.isModified():
|
||||||
ret = self.serviceManagerContents.saveModifiedService()
|
ret = self.serviceManagerContents.saveModifiedService()
|
||||||
if ret == QtGui.QMessageBox.Save:
|
if ret == QtGui.QMessageBox.Save:
|
||||||
@ -1120,6 +1310,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
Save the main window settings.
|
Save the main window settings.
|
||||||
"""
|
"""
|
||||||
|
# Exit if we just did a settings import.
|
||||||
|
if self.settingsImported:
|
||||||
|
return
|
||||||
log.debug(u'Saving QSettings')
|
log.debug(u'Saving QSettings')
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
settings.beginGroup(self.generalSettingsSection)
|
settings.beginGroup(self.generalSettingsSection)
|
||||||
|
@ -31,7 +31,7 @@ import os
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
from lxml import html
|
from lxml import html
|
||||||
|
|
||||||
from openlp.core.lib import translate, get_text_file_string
|
from openlp.core.lib import translate, get_text_file_string, Receiver
|
||||||
from openlp.core.lib.ui import UiStrings
|
from openlp.core.lib.ui import UiStrings
|
||||||
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
|
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
@ -327,12 +327,14 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
"""
|
"""
|
||||||
Copies the display text to the clipboard as plain text
|
Copies the display text to the clipboard as plain text
|
||||||
"""
|
"""
|
||||||
|
self.update_song_usage()
|
||||||
self.mainWindow.clipboard.setText(self.document.toPlainText())
|
self.mainWindow.clipboard.setText(self.document.toPlainText())
|
||||||
|
|
||||||
def copyHtmlText(self):
|
def copyHtmlText(self):
|
||||||
"""
|
"""
|
||||||
Copies the display text to the clipboard as Html
|
Copies the display text to the clipboard as Html
|
||||||
"""
|
"""
|
||||||
|
self.update_song_usage()
|
||||||
self.mainWindow.clipboard.setText(self.document.toHtml())
|
self.mainWindow.clipboard.setText(self.document.toHtml())
|
||||||
|
|
||||||
def printServiceOrder(self):
|
def printServiceOrder(self):
|
||||||
@ -341,6 +343,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
"""
|
"""
|
||||||
if not self.printDialog.exec_():
|
if not self.printDialog.exec_():
|
||||||
return
|
return
|
||||||
|
self.update_song_usage()
|
||||||
# Print the document.
|
# Print the document.
|
||||||
self.document.print_(self.printer)
|
self.document.print_(self.printer)
|
||||||
|
|
||||||
@ -397,3 +400,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
settings.setValue(u'print notes',
|
settings.setValue(u'print notes',
|
||||||
QtCore.QVariant(self.notesCheckBox.isChecked()))
|
QtCore.QVariant(self.notesCheckBox.isChecked()))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
|
def update_song_usage(self):
|
||||||
|
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||||
|
# Trigger Audit requests
|
||||||
|
Receiver.send_message(u'print_service_started',
|
||||||
|
[item[u'service_item']])
|
||||||
|
@ -290,7 +290,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
|
QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
|
||||||
# Last little bits of setting up
|
# Last little bits of setting up
|
||||||
self.service_theme = unicode(QtCore.QSettings().value(
|
self.service_theme = unicode(QtCore.QSettings().value(
|
||||||
self.mainwindow.serviceSettingsSection + u'/service theme',
|
self.mainwindow.servicemanagerSettingsSection + u'/service theme',
|
||||||
QtCore.QVariant(u'')).toString())
|
QtCore.QVariant(u'')).toString())
|
||||||
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
|
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
|
||||||
# build the drag and drop context menu
|
# build the drag and drop context menu
|
||||||
@ -371,7 +371,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.mainwindow.setServiceModified(self.isModified(),
|
self.mainwindow.setServiceModified(self.isModified(),
|
||||||
self.shortFileName())
|
self.shortFileName())
|
||||||
QtCore.QSettings(). \
|
QtCore.QSettings(). \
|
||||||
setValue(u'service/last file',QtCore.QVariant(fileName))
|
setValue(u'servicemanager/last file',QtCore.QVariant(fileName))
|
||||||
|
|
||||||
def fileName(self):
|
def fileName(self):
|
||||||
"""
|
"""
|
||||||
@ -429,14 +429,15 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.mainwindow,
|
self.mainwindow,
|
||||||
translate('OpenLP.ServiceManager', 'Open File'),
|
translate('OpenLP.ServiceManager', 'Open File'),
|
||||||
SettingsManager.get_last_dir(
|
SettingsManager.get_last_dir(
|
||||||
self.mainwindow.serviceSettingsSection),
|
self.mainwindow.servicemanagerSettingsSection),
|
||||||
translate('OpenLP.ServiceManager',
|
translate('OpenLP.ServiceManager',
|
||||||
'OpenLP Service Files (*.osz)')))
|
'OpenLP Service Files (*.osz)')))
|
||||||
if not fileName:
|
if not fileName:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
fileName = loadFile
|
fileName = loadFile
|
||||||
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
|
SettingsManager.set_last_dir(
|
||||||
|
self.mainwindow.servicemanagerSettingsSection,
|
||||||
split_filename(fileName)[0])
|
split_filename(fileName)[0])
|
||||||
self.loadFile(fileName)
|
self.loadFile(fileName)
|
||||||
|
|
||||||
@ -461,7 +462,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.setFileName(u'')
|
self.setFileName(u'')
|
||||||
self.setModified(False)
|
self.setModified(False)
|
||||||
QtCore.QSettings(). \
|
QtCore.QSettings(). \
|
||||||
setValue(u'service/last file',QtCore.QVariant(u''))
|
setValue(u'servicemanager/last file',QtCore.QVariant(u''))
|
||||||
|
|
||||||
def saveFile(self):
|
def saveFile(self):
|
||||||
"""
|
"""
|
||||||
@ -474,7 +475,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
(basename, extension) = os.path.splitext(file_name)
|
(basename, extension) = os.path.splitext(file_name)
|
||||||
service_file_name = basename + '.osd'
|
service_file_name = basename + '.osd'
|
||||||
log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
|
log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
|
||||||
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
|
SettingsManager.set_last_dir(
|
||||||
|
self.mainwindow.servicemanagerSettingsSection,
|
||||||
path)
|
path)
|
||||||
service = []
|
service = []
|
||||||
write_list = []
|
write_list = []
|
||||||
@ -562,7 +564,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
||||||
UiStrings().SaveService,
|
UiStrings().SaveService,
|
||||||
SettingsManager.get_last_dir(
|
SettingsManager.get_last_dir(
|
||||||
self.mainwindow.serviceSettingsSection),
|
self.mainwindow.servicemanagerSettingsSection),
|
||||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||||
if not fileName:
|
if not fileName:
|
||||||
return False
|
return False
|
||||||
@ -621,7 +623,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.mainwindow.addRecentFile(fileName)
|
self.mainwindow.addRecentFile(fileName)
|
||||||
self.setModified(False)
|
self.setModified(False)
|
||||||
QtCore.QSettings().setValue(
|
QtCore.QSettings().setValue(
|
||||||
'service/last file', QtCore.QVariant(fileName))
|
'servicemanager/last file', QtCore.QVariant(fileName))
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
message=translate('OpenLP.ServiceManager',
|
message=translate('OpenLP.ServiceManager',
|
||||||
@ -663,7 +665,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
present.
|
present.
|
||||||
"""
|
"""
|
||||||
fileName = QtCore.QSettings(). \
|
fileName = QtCore.QSettings(). \
|
||||||
value(u'service/last file',QtCore.QVariant(u'')).toString()
|
value(u'servicemanager/last file',QtCore.QVariant(u'')).toString()
|
||||||
if fileName:
|
if fileName:
|
||||||
self.loadFile(fileName)
|
self.loadFile(fileName)
|
||||||
|
|
||||||
@ -1005,7 +1007,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.service_theme = unicode(self.themeComboBox.currentText())
|
self.service_theme = unicode(self.themeComboBox.currentText())
|
||||||
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||||
QtCore.QSettings().setValue(
|
QtCore.QSettings().setValue(
|
||||||
self.mainwindow.serviceSettingsSection + u'/service theme',
|
self.mainwindow.servicemanagerSettingsSection +
|
||||||
|
u'/service theme',
|
||||||
QtCore.QVariant(self.service_theme))
|
QtCore.QVariant(self.service_theme))
|
||||||
self.regenerateServiceItems()
|
self.regenerateServiceItems()
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
self.onGradientComboBoxCurrentIndexChanged)
|
self.onGradientComboBoxCurrentIndexChanged)
|
||||||
QtCore.QObject.connect(self.colorButton,
|
QtCore.QObject.connect(self.colorButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onColorButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onColorButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.imageColorButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'), self.onImageColorButtonClicked)
|
||||||
QtCore.QObject.connect(self.gradientStartButton,
|
QtCore.QObject.connect(self.gradientStartButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onGradientStartButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onGradientStartButtonClicked)
|
||||||
QtCore.QObject.connect(self.gradientEndButton,
|
QtCore.QObject.connect(self.gradientEndButton,
|
||||||
@ -330,6 +332,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
self.theme.background_end_color)
|
self.theme.background_end_color)
|
||||||
self.setField(u'background_type', QtCore.QVariant(1))
|
self.setField(u'background_type', QtCore.QVariant(1))
|
||||||
else:
|
else:
|
||||||
|
self.imageColorButton.setStyleSheet(u'background-color: %s' %
|
||||||
|
self.theme.background_border_color)
|
||||||
self.imageFileEdit.setText(self.theme.background_filename)
|
self.imageFileEdit.setText(self.theme.background_filename)
|
||||||
self.setField(u'background_type', QtCore.QVariant(2))
|
self.setField(u'background_type', QtCore.QVariant(2))
|
||||||
if self.theme.background_direction == \
|
if self.theme.background_direction == \
|
||||||
@ -464,6 +468,14 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
self._colorButton(self.theme.background_color)
|
self._colorButton(self.theme.background_color)
|
||||||
self.setBackgroundPageValues()
|
self.setBackgroundPageValues()
|
||||||
|
|
||||||
|
def onImageColorButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Background / Gradient 1 Color button pushed.
|
||||||
|
"""
|
||||||
|
self.theme.background_border_color = \
|
||||||
|
self._colorButton(self.theme.background_border_color)
|
||||||
|
self.setBackgroundPageValues()
|
||||||
|
|
||||||
def onGradientStartButtonClicked(self):
|
def onGradientStartButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
Gradient 2 Color button pushed.
|
Gradient 2 Color button pushed.
|
||||||
@ -564,7 +576,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""
|
"""
|
||||||
Lets save the them as Finish has been pressed
|
Lets save the theme as Finish has been pressed
|
||||||
"""
|
"""
|
||||||
# Save the theme name
|
# Save the theme name
|
||||||
self.theme.theme_name = unicode(self.field(u'name').toString())
|
self.theme.theme_name = unicode(self.field(u'name').toString())
|
||||||
|
@ -610,6 +610,11 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
and to trigger the reload of the theme list
|
and to trigger the reload of the theme list
|
||||||
"""
|
"""
|
||||||
self._writeTheme(theme, imageFrom, imageTo)
|
self._writeTheme(theme, imageFrom, imageTo)
|
||||||
|
if theme.background_type == \
|
||||||
|
BackgroundType.to_string(BackgroundType.Image):
|
||||||
|
self.mainwindow.imageManager.update_image(theme.theme_name,
|
||||||
|
u'theme', QtGui.QColor(theme.background_border_color))
|
||||||
|
self.mainwindow.imageManager.process_updates()
|
||||||
self.loadThemes()
|
self.loadThemes()
|
||||||
|
|
||||||
def _writeTheme(self, theme, imageFrom, imageTo):
|
def _writeTheme(self, theme, imageFrom, imageTo):
|
||||||
|
@ -105,6 +105,11 @@ class Ui_ThemeWizard(object):
|
|||||||
self.imageLayout = QtGui.QFormLayout(self.imageWidget)
|
self.imageLayout = QtGui.QFormLayout(self.imageWidget)
|
||||||
self.imageLayout.setMargin(0)
|
self.imageLayout.setMargin(0)
|
||||||
self.imageLayout.setObjectName(u'ImageLayout')
|
self.imageLayout.setObjectName(u'ImageLayout')
|
||||||
|
self.imageColorLabel = QtGui.QLabel(self.colorWidget)
|
||||||
|
self.imageColorLabel.setObjectName(u'ImageColorLabel')
|
||||||
|
self.imageColorButton = QtGui.QPushButton(self.colorWidget)
|
||||||
|
self.imageColorButton.setObjectName(u'ImageColorButton')
|
||||||
|
self.imageLayout.addRow(self.imageColorLabel, self.imageColorButton)
|
||||||
self.imageLabel = QtGui.QLabel(self.imageWidget)
|
self.imageLabel = QtGui.QLabel(self.imageWidget)
|
||||||
self.imageLabel.setObjectName(u'ImageLabel')
|
self.imageLabel.setObjectName(u'ImageLabel')
|
||||||
self.imageFileLayout = QtGui.QHBoxLayout()
|
self.imageFileLayout = QtGui.QHBoxLayout()
|
||||||
@ -118,7 +123,7 @@ class Ui_ThemeWizard(object):
|
|||||||
build_icon(u':/general/general_open.png'))
|
build_icon(u':/general/general_open.png'))
|
||||||
self.imageFileLayout.addWidget(self.imageBrowseButton)
|
self.imageFileLayout.addWidget(self.imageBrowseButton)
|
||||||
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
|
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
|
||||||
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
self.imageLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||||
self.backgroundStack.addWidget(self.imageWidget)
|
self.backgroundStack.addWidget(self.imageWidget)
|
||||||
self.backgroundLayout.addLayout(self.backgroundStack)
|
self.backgroundLayout.addLayout(self.backgroundStack)
|
||||||
themeWizard.addPage(self.backgroundPage)
|
themeWizard.addPage(self.backgroundPage)
|
||||||
@ -443,6 +448,8 @@ class Ui_ThemeWizard(object):
|
|||||||
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
||||||
self.gradientComboBox.setItemText(BackgroundGradientType.LeftBottom,
|
self.gradientComboBox.setItemText(BackgroundGradientType.LeftBottom,
|
||||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||||
|
self.imageColorLabel.setText(
|
||||||
|
translate(u'OpenLP.ThemeWizard', 'Background color:'))
|
||||||
self.imageLabel.setText(u'%s:' % UiStrings().Image)
|
self.imageLabel.setText(u'%s:' % UiStrings().Image)
|
||||||
self.mainAreaPage.setTitle(
|
self.mainAreaPage.setTitle(
|
||||||
translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
||||||
|
@ -386,6 +386,17 @@ def split_filename(path):
|
|||||||
else:
|
else:
|
||||||
return os.path.split(path)
|
return os.path.split(path)
|
||||||
|
|
||||||
|
def clean_filename(filename):
|
||||||
|
"""
|
||||||
|
Removes invalid characters from the given ``filename``.
|
||||||
|
|
||||||
|
``filename``
|
||||||
|
The "dirty" file name to clean.
|
||||||
|
"""
|
||||||
|
if not isinstance(filename, unicode):
|
||||||
|
filename = unicode(filename, u'utf-8')
|
||||||
|
return re.sub(r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
|
||||||
|
|
||||||
def delete_file(file_path_name):
|
def delete_file(file_path_name):
|
||||||
"""
|
"""
|
||||||
Deletes a file from the system.
|
Deletes a file from the system.
|
||||||
@ -492,4 +503,4 @@ from actions import ActionList
|
|||||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||||
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
||||||
u'get_uno_instance', u'delete_file']
|
u'get_uno_instance', u'delete_file', u'clean_filename']
|
||||||
|
@ -44,85 +44,85 @@ class AlertsTab(SettingsTab):
|
|||||||
self.fontGroupBox.setObjectName(u'fontGroupBox')
|
self.fontGroupBox.setObjectName(u'fontGroupBox')
|
||||||
self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
|
self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
|
||||||
self.fontLayout.setObjectName(u'fontLayout')
|
self.fontLayout.setObjectName(u'fontLayout')
|
||||||
self.FontLabel = QtGui.QLabel(self.fontGroupBox)
|
self.fontLabel = QtGui.QLabel(self.fontGroupBox)
|
||||||
self.FontLabel.setObjectName(u'FontLabel')
|
self.fontLabel.setObjectName(u'fontLabel')
|
||||||
self.FontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
|
self.fontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
|
||||||
self.FontComboBox.setObjectName(u'FontComboBox')
|
self.fontComboBox.setObjectName(u'fontComboBox')
|
||||||
self.fontLayout.addRow(self.FontLabel, self.FontComboBox)
|
self.fontLayout.addRow(self.fontLabel, self.fontComboBox)
|
||||||
self.FontColorLabel = QtGui.QLabel(self.fontGroupBox)
|
self.fontColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||||
self.FontColorLabel.setObjectName(u'FontColorLabel')
|
self.fontColorLabel.setObjectName(u'fontColorLabel')
|
||||||
self.ColorLayout = QtGui.QHBoxLayout()
|
self.colorLayout = QtGui.QHBoxLayout()
|
||||||
self.ColorLayout.setObjectName(u'ColorLayout')
|
self.colorLayout.setObjectName(u'colorLayout')
|
||||||
self.FontColorButton = QtGui.QPushButton(self.fontGroupBox)
|
self.fontColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||||
self.FontColorButton.setObjectName(u'FontColorButton')
|
self.fontColorButton.setObjectName(u'fontColorButton')
|
||||||
self.ColorLayout.addWidget(self.FontColorButton)
|
self.colorLayout.addWidget(self.fontColorButton)
|
||||||
self.ColorLayout.addSpacing(20)
|
self.colorLayout.addSpacing(20)
|
||||||
self.BackgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
|
self.backgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||||
self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel')
|
self.backgroundColorLabel.setObjectName(u'backgroundColorLabel')
|
||||||
self.ColorLayout.addWidget(self.BackgroundColorLabel)
|
self.colorLayout.addWidget(self.backgroundColorLabel)
|
||||||
self.BackgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
|
self.backgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||||
self.BackgroundColorButton.setObjectName(u'BackgroundColorButton')
|
self.backgroundColorButton.setObjectName(u'backgroundColorButton')
|
||||||
self.ColorLayout.addWidget(self.BackgroundColorButton)
|
self.colorLayout.addWidget(self.backgroundColorButton)
|
||||||
self.fontLayout.addRow(self.FontColorLabel, self.ColorLayout)
|
self.fontLayout.addRow(self.fontColorLabel, self.colorLayout)
|
||||||
self.FontSizeLabel = QtGui.QLabel(self.fontGroupBox)
|
self.fontSizeLabel = QtGui.QLabel(self.fontGroupBox)
|
||||||
self.FontSizeLabel.setObjectName(u'FontSizeLabel')
|
self.fontSizeLabel.setObjectName(u'fontSizeLabel')
|
||||||
self.FontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
self.fontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||||
self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox')
|
self.fontSizeSpinBox.setObjectName(u'fontSizeSpinBox')
|
||||||
self.fontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
|
self.fontLayout.addRow(self.fontSizeLabel, self.fontSizeSpinBox)
|
||||||
self.TimeoutLabel = QtGui.QLabel(self.fontGroupBox)
|
self.timeoutLabel = QtGui.QLabel(self.fontGroupBox)
|
||||||
self.TimeoutLabel.setObjectName(u'TimeoutLabel')
|
self.timeoutLabel.setObjectName(u'timeoutLabel')
|
||||||
self.TimeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
self.timeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||||
self.TimeoutSpinBox.setMaximum(180)
|
self.timeoutSpinBox.setMaximum(180)
|
||||||
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
|
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
|
||||||
self.fontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
|
self.fontLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
|
||||||
create_valign_combo(self, self.fontGroupBox, self.fontLayout)
|
create_valign_combo(self, self.fontGroupBox, self.fontLayout)
|
||||||
self.leftLayout.addWidget(self.fontGroupBox)
|
self.leftLayout.addWidget(self.fontGroupBox)
|
||||||
self.leftLayout.addStretch()
|
self.leftLayout.addStretch()
|
||||||
self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn)
|
self.previewGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
self.PreviewGroupBox.setObjectName(u'PreviewGroupBox')
|
self.previewGroupBox.setObjectName(u'previewGroupBox')
|
||||||
self.PreviewLayout = QtGui.QVBoxLayout(self.PreviewGroupBox)
|
self.previewLayout = QtGui.QVBoxLayout(self.previewGroupBox)
|
||||||
self.PreviewLayout.setObjectName(u'PreviewLayout')
|
self.previewLayout.setObjectName(u'previewLayout')
|
||||||
self.FontPreview = QtGui.QLineEdit(self.PreviewGroupBox)
|
self.fontPreview = QtGui.QLineEdit(self.previewGroupBox)
|
||||||
self.FontPreview.setObjectName(u'FontPreview')
|
self.fontPreview.setObjectName(u'fontPreview')
|
||||||
self.PreviewLayout.addWidget(self.FontPreview)
|
self.previewLayout.addWidget(self.fontPreview)
|
||||||
self.rightLayout.addWidget(self.PreviewGroupBox)
|
self.rightLayout.addWidget(self.previewGroupBox)
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
QtCore.QObject.connect(self.BackgroundColorButton,
|
QtCore.QObject.connect(self.backgroundColorButton,
|
||||||
QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
|
QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
|
||||||
QtCore.QObject.connect(self.FontColorButton,
|
QtCore.QObject.connect(self.fontColorButton,
|
||||||
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
|
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
|
||||||
QtCore.QObject.connect(self.FontComboBox,
|
QtCore.QObject.connect(self.fontComboBox,
|
||||||
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
|
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
|
||||||
QtCore.QObject.connect(self.TimeoutSpinBox,
|
QtCore.QObject.connect(self.timeoutSpinBox,
|
||||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
|
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
|
||||||
QtCore.QObject.connect(self.FontSizeSpinBox,
|
QtCore.QObject.connect(self.fontSizeSpinBox,
|
||||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
|
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.fontGroupBox.setTitle(
|
self.fontGroupBox.setTitle(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Font'))
|
translate('AlertsPlugin.AlertsTab', 'Font'))
|
||||||
self.FontLabel.setText(
|
self.fontLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Font name:'))
|
translate('AlertsPlugin.AlertsTab', 'Font name:'))
|
||||||
self.FontColorLabel.setText(
|
self.fontColorLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Font color:'))
|
translate('AlertsPlugin.AlertsTab', 'Font color:'))
|
||||||
self.BackgroundColorLabel.setText(
|
self.backgroundColorLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Background color:'))
|
translate('AlertsPlugin.AlertsTab', 'Background color:'))
|
||||||
self.FontSizeLabel.setText(
|
self.fontSizeLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Font size:'))
|
translate('AlertsPlugin.AlertsTab', 'Font size:'))
|
||||||
self.FontSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
self.fontSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.TimeoutLabel.setText(
|
self.timeoutLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
||||||
self.TimeoutSpinBox.setSuffix(UiStrings().Seconds)
|
self.timeoutSpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.PreviewGroupBox.setTitle(UiStrings().Preview)
|
self.previewGroupBox.setTitle(UiStrings().Preview)
|
||||||
self.FontPreview.setText(UiStrings().OLPV2)
|
self.fontPreview.setText(UiStrings().OLPV2)
|
||||||
|
|
||||||
def onBackgroundColorButtonClicked(self):
|
def onBackgroundColorButtonClicked(self):
|
||||||
new_color = QtGui.QColorDialog.getColor(
|
new_color = QtGui.QColorDialog.getColor(
|
||||||
QtGui.QColor(self.bg_color), self)
|
QtGui.QColor(self.bg_color), self)
|
||||||
if new_color.isValid():
|
if new_color.isValid():
|
||||||
self.bg_color = new_color.name()
|
self.bg_color = new_color.name()
|
||||||
self.BackgroundColorButton.setStyleSheet(
|
self.backgroundColorButton.setStyleSheet(
|
||||||
u'background-color: %s' % self.bg_color)
|
u'background-color: %s' % self.bg_color)
|
||||||
self.updateDisplay()
|
self.updateDisplay()
|
||||||
|
|
||||||
@ -134,15 +134,15 @@ class AlertsTab(SettingsTab):
|
|||||||
QtGui.QColor(self.font_color), self)
|
QtGui.QColor(self.font_color), self)
|
||||||
if new_color.isValid():
|
if new_color.isValid():
|
||||||
self.font_color = new_color.name()
|
self.font_color = new_color.name()
|
||||||
self.FontColorButton.setStyleSheet(
|
self.fontColorButton.setStyleSheet(
|
||||||
u'background-color: %s' % self.font_color)
|
u'background-color: %s' % self.font_color)
|
||||||
self.updateDisplay()
|
self.updateDisplay()
|
||||||
|
|
||||||
def onTimeoutSpinBoxChanged(self):
|
def onTimeoutSpinBoxChanged(self):
|
||||||
self.timeout = self.TimeoutSpinBox.value()
|
self.timeout = self.timeoutSpinBox.value()
|
||||||
|
|
||||||
def onFontSizeSpinBoxChanged(self):
|
def onFontSizeSpinBoxChanged(self):
|
||||||
self.font_size = self.FontSizeSpinBox.value()
|
self.font_size = self.fontSizeSpinBox.value()
|
||||||
self.updateDisplay()
|
self.updateDisplay()
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@ -160,16 +160,16 @@ class AlertsTab(SettingsTab):
|
|||||||
self.location = settings.value(
|
self.location = settings.value(
|
||||||
u'location', QtCore.QVariant(1)).toInt()[0]
|
u'location', QtCore.QVariant(1)).toInt()[0]
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
self.FontSizeSpinBox.setValue(self.font_size)
|
self.fontSizeSpinBox.setValue(self.font_size)
|
||||||
self.TimeoutSpinBox.setValue(self.timeout)
|
self.timeoutSpinBox.setValue(self.timeout)
|
||||||
self.FontColorButton.setStyleSheet(
|
self.fontColorButton.setStyleSheet(
|
||||||
u'background-color: %s' % self.font_color)
|
u'background-color: %s' % self.font_color)
|
||||||
self.BackgroundColorButton.setStyleSheet(
|
self.backgroundColorButton.setStyleSheet(
|
||||||
u'background-color: %s' % self.bg_color)
|
u'background-color: %s' % self.bg_color)
|
||||||
self.verticalComboBox.setCurrentIndex(self.location)
|
self.verticalComboBox.setCurrentIndex(self.location)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setFamily(self.font_face)
|
font.setFamily(self.font_face)
|
||||||
self.FontComboBox.setCurrentFont(font)
|
self.fontComboBox.setCurrentFont(font)
|
||||||
self.updateDisplay()
|
self.updateDisplay()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -178,7 +178,7 @@ class AlertsTab(SettingsTab):
|
|||||||
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
||||||
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
|
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
|
||||||
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
|
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
|
||||||
self.font_face = self.FontComboBox.currentFont().family()
|
self.font_face = self.fontComboBox.currentFont().family()
|
||||||
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
|
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
|
||||||
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
|
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
|
||||||
self.location = self.verticalComboBox.currentIndex()
|
self.location = self.verticalComboBox.currentIndex()
|
||||||
@ -187,10 +187,10 @@ class AlertsTab(SettingsTab):
|
|||||||
|
|
||||||
def updateDisplay(self):
|
def updateDisplay(self):
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setFamily(self.FontComboBox.currentFont().family())
|
font.setFamily(self.fontComboBox.currentFont().family())
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setPointSize(self.font_size)
|
font.setPointSize(self.font_size)
|
||||||
self.FontPreview.setFont(font)
|
self.fontPreview.setFont(font)
|
||||||
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
self.fontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
||||||
(self.bg_color, self.font_color))
|
(self.bg_color, self.font_color))
|
||||||
|
|
||||||
|
@ -29,17 +29,17 @@ The bible import functions for OpenLP
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
from tempfile import gettempdir
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, SettingsManager, translate, \
|
from openlp.core.lib import Receiver, SettingsManager, translate, \
|
||||||
check_directory_exists
|
check_directory_exists
|
||||||
from openlp.core.lib.db import delete_database
|
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.core.utils import AppLocation, delete_file
|
from openlp.core.utils import AppLocation, delete_file
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB, \
|
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB, \
|
||||||
BiblesResourcesDB, clean_filename
|
BiblesResourcesDB
|
||||||
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -70,6 +70,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.suffix = u'.sqlite'
|
self.suffix = u'.sqlite'
|
||||||
self.settingsSection = u'bibles'
|
self.settingsSection = u'bibles'
|
||||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||||
|
self.temp_dir = os.path.join(gettempdir(), u'openlp')
|
||||||
self.files = self.manager.old_bible_databases
|
self.files = self.manager.old_bible_databases
|
||||||
self.success = {}
|
self.success = {}
|
||||||
self.newbibles = {}
|
self.newbibles = {}
|
||||||
@ -91,20 +92,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
log.debug(u'Stopping import')
|
log.debug(u'Stopping import')
|
||||||
self.stop_import_flag = True
|
self.stop_import_flag = True
|
||||||
|
|
||||||
def onCheckBoxIndexChanged(self, index):
|
|
||||||
"""
|
|
||||||
Show/Hide warnings if CheckBox state has changed
|
|
||||||
"""
|
|
||||||
for number, filename in enumerate(self.files):
|
|
||||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
|
||||||
self.verticalWidget[number].hide()
|
|
||||||
self.formWidget[number].hide()
|
|
||||||
else:
|
|
||||||
version_name = unicode(self.versionNameEdit[number].text())
|
|
||||||
if self.manager.exists(version_name):
|
|
||||||
self.verticalWidget[number].show()
|
|
||||||
self.formWidget[number].show()
|
|
||||||
|
|
||||||
def reject(self):
|
def reject(self):
|
||||||
"""
|
"""
|
||||||
Stop the wizard on cancel button, close button or ESC key.
|
Stop the wizard on cancel button, close button or ESC key.
|
||||||
@ -113,8 +100,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.stop_import_flag = True
|
self.stop_import_flag = True
|
||||||
if not self.currentPage() == self.progressPage:
|
if not self.currentPage() == self.progressPage:
|
||||||
self.done(QtGui.QDialog.Rejected)
|
self.done(QtGui.QDialog.Rejected)
|
||||||
else:
|
|
||||||
self.postWizard()
|
|
||||||
|
|
||||||
def onCurrentIdChanged(self, pageId):
|
def onCurrentIdChanged(self, pageId):
|
||||||
"""
|
"""
|
||||||
@ -124,7 +109,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.preWizard()
|
self.preWizard()
|
||||||
self.performWizard()
|
self.performWizard()
|
||||||
self.postWizard()
|
self.postWizard()
|
||||||
elif self.page(pageId) == self.selectPage and self.maxBibles == 0:
|
elif self.page(pageId) == self.selectPage and not self.files:
|
||||||
self.next()
|
self.next()
|
||||||
|
|
||||||
def onBackupBrowseButtonClicked(self):
|
def onBackupBrowseButtonClicked(self):
|
||||||
@ -243,78 +228,13 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
Add the content to the scrollArea.
|
Add the content to the scrollArea.
|
||||||
"""
|
"""
|
||||||
self.checkBox = {}
|
self.checkBox = {}
|
||||||
self.versionNameEdit = {}
|
|
||||||
self.versionNameLabel = {}
|
|
||||||
self.versionInfoLabel = {}
|
|
||||||
self.versionInfoPixmap = {}
|
|
||||||
self.verticalWidget = {}
|
|
||||||
self.horizontalLayout = {}
|
|
||||||
self.formWidget = {}
|
|
||||||
self.formLayoutAttention = {}
|
|
||||||
for number, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
bible = OldBibleDB(self.mediaItem, path=self.path, file=filename[0])
|
bible = OldBibleDB(self.mediaItem, path=self.path, file=filename[0])
|
||||||
self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
|
self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
|
||||||
checkBoxName = u'checkBox[%d]' % number
|
self.checkBox[number].setObjectName(u'checkBox[%d]' % number)
|
||||||
self.checkBox[number].setObjectName(checkBoxName)
|
|
||||||
self.checkBox[number].setText(bible.get_name())
|
self.checkBox[number].setText(bible.get_name())
|
||||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||||
self.formLayout.addWidget(self.checkBox[number])
|
self.formLayout.addWidget(self.checkBox[number])
|
||||||
self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
|
||||||
verticalWidgetName = u'verticalWidget[%d]' % number
|
|
||||||
self.verticalWidget[number].setObjectName(verticalWidgetName)
|
|
||||||
self.horizontalLayout[number] = QtGui.QHBoxLayout(
|
|
||||||
self.verticalWidget[number])
|
|
||||||
self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0)
|
|
||||||
horizontalLayoutName = u'horizontalLayout[%d]' % number
|
|
||||||
self.horizontalLayout[number].setObjectName(horizontalLayoutName)
|
|
||||||
self.versionInfoPixmap[number] = QtGui.QLabel(
|
|
||||||
self.verticalWidget[number])
|
|
||||||
versionInfoPixmapName = u'versionInfoPixmap[%d]' % number
|
|
||||||
self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName)
|
|
||||||
self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap(
|
|
||||||
u':/bibles/bibles_upgrade_alert.png'))
|
|
||||||
self.versionInfoPixmap[number].setAlignment(QtCore.Qt.AlignRight)
|
|
||||||
self.horizontalLayout[number].addWidget(
|
|
||||||
self.versionInfoPixmap[number])
|
|
||||||
self.versionInfoLabel[number] = QtGui.QLabel(
|
|
||||||
self.verticalWidget[number])
|
|
||||||
versionInfoLabelName = u'versionInfoLabel[%d]' % number
|
|
||||||
self.versionInfoLabel[number].setObjectName(versionInfoLabelName)
|
|
||||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
|
|
||||||
QtGui.QSizePolicy.Preferred)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(
|
|
||||||
self.versionInfoLabel[number].sizePolicy().hasHeightForWidth())
|
|
||||||
self.versionInfoLabel[number].setSizePolicy(sizePolicy)
|
|
||||||
self.horizontalLayout[number].addWidget(
|
|
||||||
self.versionInfoLabel[number])
|
|
||||||
self.formLayout.addWidget(self.verticalWidget[number])
|
|
||||||
self.formWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
|
||||||
formWidgetName = u'formWidget[%d]' % number
|
|
||||||
self.formWidget[number].setObjectName(formWidgetName)
|
|
||||||
self.formLayoutAttention[number] = QtGui.QFormLayout(
|
|
||||||
self.formWidget[number])
|
|
||||||
self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5)
|
|
||||||
formLayoutAttentionName = u'formLayoutAttention[%d]' % number
|
|
||||||
self.formLayoutAttention[number].setObjectName(
|
|
||||||
formLayoutAttentionName)
|
|
||||||
self.versionNameLabel[number] = QtGui.QLabel(
|
|
||||||
self.formWidget[number])
|
|
||||||
self.versionNameLabel[number].setObjectName(u'VersionNameLabel')
|
|
||||||
self.formLayoutAttention[number].setWidget(0,
|
|
||||||
QtGui.QFormLayout.LabelRole, self.versionNameLabel[number])
|
|
||||||
self.versionNameEdit[number] = QtGui.QLineEdit(
|
|
||||||
self.formWidget[number])
|
|
||||||
self.versionNameEdit[number].setObjectName(u'VersionNameEdit')
|
|
||||||
self.formLayoutAttention[number].setWidget(0,
|
|
||||||
QtGui.QFormLayout.FieldRole, self.versionNameEdit[number])
|
|
||||||
self.versionNameEdit[number].setText(bible.get_name())
|
|
||||||
self.formLayout.addWidget(self.formWidget[number])
|
|
||||||
# Set up the Signal for the checkbox.
|
|
||||||
QtCore.QObject.connect(self.checkBox[number],
|
|
||||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
|
||||||
self.onCheckBoxIndexChanged)
|
|
||||||
self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum,
|
self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum,
|
||||||
QtGui.QSizePolicy.Expanding)
|
QtGui.QSizePolicy.Expanding)
|
||||||
self.formLayout.addItem(self.spacerItem)
|
self.formLayout.addItem(self.spacerItem)
|
||||||
@ -327,23 +247,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
for number, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
self.formLayout.removeWidget(self.checkBox[number])
|
self.formLayout.removeWidget(self.checkBox[number])
|
||||||
self.checkBox[number].setParent(None)
|
self.checkBox[number].setParent(None)
|
||||||
self.horizontalLayout[number].removeWidget(
|
|
||||||
self.versionInfoPixmap[number])
|
|
||||||
self.versionInfoPixmap[number].setParent(None)
|
|
||||||
self.horizontalLayout[number].removeWidget(
|
|
||||||
self.versionInfoLabel[number])
|
|
||||||
self.versionInfoLabel[number].setParent(None)
|
|
||||||
self.formLayout.removeWidget(self.verticalWidget[number])
|
|
||||||
self.verticalWidget[number].setParent(None)
|
|
||||||
self.formLayoutAttention[number].removeWidget(
|
|
||||||
self.versionNameLabel[number])
|
|
||||||
self.versionNameLabel[number].setParent(None)
|
|
||||||
self.formLayoutAttention[number].removeWidget(
|
|
||||||
self.versionNameEdit[number])
|
|
||||||
self.formLayoutAttention[number].deleteLater()
|
|
||||||
self.versionNameEdit[number].setParent(None)
|
|
||||||
self.formLayout.removeWidget(self.formWidget[number])
|
|
||||||
self.formWidget[number].setParent(None)
|
|
||||||
self.formLayout.removeItem(self.spacerItem)
|
self.formLayout.removeItem(self.spacerItem)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
@ -385,12 +288,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.selectPage.setSubTitle(
|
self.selectPage.setSubTitle(
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
translate('BiblesPlugin.UpgradeWizardForm',
|
||||||
'Please select the Bibles to upgrade'))
|
'Please select the Bibles to upgrade'))
|
||||||
for number, bible in enumerate(self.files):
|
|
||||||
self.versionNameLabel[number].setText(
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm', 'Version name:'))
|
|
||||||
self.versionInfoLabel[number].setText(
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm', 'This '
|
|
||||||
'Bible still exists. Please change the name or uncheck it.'))
|
|
||||||
self.progressPage.setTitle(translate('BiblesPlugin.UpgradeWizardForm',
|
self.progressPage.setTitle(translate('BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading'))
|
'Upgrading'))
|
||||||
self.progressPage.setSubTitle(
|
self.progressPage.setSubTitle(
|
||||||
@ -425,58 +322,16 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
elif self.currentPage() == self.selectPage:
|
elif self.currentPage() == self.selectPage:
|
||||||
|
check_directory_exists(self.temp_dir)
|
||||||
for number, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||||
continue
|
continue
|
||||||
version_name = unicode(self.versionNameEdit[number].text())
|
# Move bibles to temp dir.
|
||||||
if not version_name:
|
if not os.path.exists(os.path.join(self.temp_dir, filename[0])):
|
||||||
critical_error_message_box(UiStrings().EmptyField,
|
shutil.move(
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
os.path.join(self.path, filename[0]), self.temp_dir)
|
||||||
'You need to specify a version name for your Bible.'))
|
else:
|
||||||
self.versionNameEdit[number].setFocus()
|
delete_file(os.path.join(self.path, filename[0]))
|
||||||
return False
|
|
||||||
elif self.manager.exists(version_name):
|
|
||||||
critical_error_message_box(
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'Bible Exists'),
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'This Bible already exists. Please upgrade '
|
|
||||||
'a different Bible, delete the existing one or '
|
|
||||||
'uncheck.'))
|
|
||||||
self.versionNameEdit[number].setFocus()
|
|
||||||
return False
|
|
||||||
elif os.path.exists(os.path.join(self.path, clean_filename(
|
|
||||||
version_name))) and version_name == filename[1]:
|
|
||||||
newfilename = u'old_database_%s' % filename[0]
|
|
||||||
if not os.path.exists(os.path.join(self.path,
|
|
||||||
newfilename)):
|
|
||||||
os.rename(os.path.join(self.path, filename[0]),
|
|
||||||
os.path.join(self.path, newfilename))
|
|
||||||
self.files[number] = [newfilename, filename[1]]
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
critical_error_message_box(
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'Bible Exists'),
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'This Bible already exists. Please upgrade '
|
|
||||||
'a different Bible, delete the existing one or '
|
|
||||||
'uncheck.'))
|
|
||||||
self.verticalWidget[number].show()
|
|
||||||
self.formWidget[number].show()
|
|
||||||
self.versionNameEdit[number].setFocus()
|
|
||||||
return False
|
|
||||||
elif os.path.exists(os.path.join(self.path,
|
|
||||||
clean_filename(version_name))):
|
|
||||||
critical_error_message_box(
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'Bible Exists'),
|
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'This Bible already exists. Please upgrade '
|
|
||||||
'a different Bible, delete the existing one or '
|
|
||||||
'uncheck.'))
|
|
||||||
self.versionNameEdit[number].setFocus()
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
if self.currentPage() == self.progressPage:
|
if self.currentPage() == self.progressPage:
|
||||||
return True
|
return True
|
||||||
@ -495,16 +350,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.files = self.manager.old_bible_databases
|
self.files = self.manager.old_bible_databases
|
||||||
self.addScrollArea()
|
self.addScrollArea()
|
||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
self.maxBibles = len(self.files)
|
|
||||||
for number, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||||
oldname = filename[1]
|
|
||||||
if self.manager.exists(oldname):
|
|
||||||
self.verticalWidget[number].show()
|
|
||||||
self.formWidget[number].show()
|
|
||||||
else:
|
|
||||||
self.verticalWidget[number].hide()
|
|
||||||
self.formWidget[number].hide()
|
|
||||||
self.progressBar.show()
|
self.progressBar.show()
|
||||||
self.restart()
|
self.restart()
|
||||||
self.finishButton.setVisible(False)
|
self.finishButton.setVisible(False)
|
||||||
@ -516,9 +363,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
Prepare the UI for the upgrade.
|
Prepare the UI for the upgrade.
|
||||||
"""
|
"""
|
||||||
OpenLPWizard.preWizard(self)
|
OpenLPWizard.preWizard(self)
|
||||||
self.progressLabel.setText(translate(
|
self.progressLabel.setText(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
translate('BiblesPlugin.UpgradeWizardForm', 'Starting upgrade...'))
|
||||||
'Starting upgrade...'))
|
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
|
||||||
def performWizard(self):
|
def performWizard(self):
|
||||||
@ -527,48 +373,42 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
self.include_webbible = False
|
self.include_webbible = False
|
||||||
proxy_server = None
|
proxy_server = None
|
||||||
if self.maxBibles == 0:
|
if not self.files:
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(
|
||||||
translate('BiblesPlugin.UpgradeWizardForm', 'There are no '
|
translate('BiblesPlugin.UpgradeWizardForm', 'There are no '
|
||||||
'Bibles that need to be upgraded.'))
|
'Bibles that need to be upgraded.'))
|
||||||
self.progressBar.hide()
|
self.progressBar.hide()
|
||||||
return
|
return
|
||||||
self.maxBibles = 0
|
max_bibles = 0
|
||||||
for number, file in enumerate(self.files):
|
for number, file in enumerate(self.files):
|
||||||
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||||
self.maxBibles += 1
|
max_bibles += 1
|
||||||
number = 0
|
oldBible = None
|
||||||
for biblenumber, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
|
# Close the previous bible's connection.
|
||||||
|
if oldBible is not None:
|
||||||
|
oldBible.close_connection()
|
||||||
|
# Set to None to make obvious that we have already closed the
|
||||||
|
# database.
|
||||||
|
oldBible = None
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
bible_failed = False
|
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||||
self.success[biblenumber] = False
|
self.success[number] = False
|
||||||
if not self.checkBox[biblenumber].checkState() == QtCore.Qt.Checked:
|
|
||||||
continue
|
continue
|
||||||
self.progressBar.reset()
|
self.progressBar.reset()
|
||||||
oldbible = OldBibleDB(self.mediaItem, path=self.path,
|
oldBible = OldBibleDB(self.mediaItem, path=self.temp_dir,
|
||||||
file=filename[0])
|
file=filename[0])
|
||||||
name = filename[1]
|
name = filename[1]
|
||||||
if name is None:
|
|
||||||
delete_file(os.path.join(self.path, filename[0]))
|
|
||||||
self.incrementProgressBar(unicode(translate(
|
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
|
||||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
|
||||||
(number + 1, self.maxBibles, name),
|
|
||||||
self.progressBar.maximum() - self.progressBar.value())
|
|
||||||
number += 1
|
|
||||||
continue
|
|
||||||
self.progressLabel.setText(unicode(translate(
|
self.progressLabel.setText(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\nUpgrading ...')) %
|
'Upgrading Bible %s of %s: "%s"\nUpgrading ...')) %
|
||||||
(number + 1, self.maxBibles, name))
|
(number + 1, max_bibles, name))
|
||||||
if os.path.exists(os.path.join(self.path, filename[0])):
|
|
||||||
name = unicode(self.versionNameEdit[biblenumber].text())
|
|
||||||
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
|
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
|
||||||
name=name)
|
name=name, file=filename[0])
|
||||||
self.newbibles[number].register(self.plugin.upgrade_wizard)
|
self.newbibles[number].register(self.plugin.upgrade_wizard)
|
||||||
metadata = oldbible.get_metadata()
|
metadata = oldBible.get_metadata()
|
||||||
webbible = False
|
webbible = False
|
||||||
meta_data = {}
|
meta_data = {}
|
||||||
for meta in metadata:
|
for meta in metadata:
|
||||||
@ -595,7 +435,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
u'name: "%s" failed' % (
|
u'name: "%s" failed' % (
|
||||||
meta_data[u'download source'],
|
meta_data[u'download source'],
|
||||||
meta_data[u'download name']))
|
meta_data[u'download name']))
|
||||||
delete_database(self.path, clean_filename(name))
|
self.newbibles[number].session.close()
|
||||||
del self.newbibles[number]
|
del self.newbibles[number]
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('BiblesPlugin.UpgradeWizardForm',
|
translate('BiblesPlugin.UpgradeWizardForm',
|
||||||
@ -606,9 +446,9 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||||
(number + 1, self.maxBibles, name),
|
(number + 1, max_bibles, name),
|
||||||
self.progressBar.maximum() - self.progressBar.value())
|
self.progressBar.maximum() - self.progressBar.value())
|
||||||
number += 1
|
self.success[number] = False
|
||||||
continue
|
continue
|
||||||
bible = BiblesResourcesDB.get_webbible(
|
bible = BiblesResourcesDB.get_webbible(
|
||||||
meta_data[u'download name'],
|
meta_data[u'download name'],
|
||||||
@ -621,25 +461,25 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
language_id = self.newbibles[number].get_language(name)
|
language_id = self.newbibles[number].get_language(name)
|
||||||
if not language_id:
|
if not language_id:
|
||||||
log.warn(u'Upgrading from "%s" failed' % filename[0])
|
log.warn(u'Upgrading from "%s" failed' % filename[0])
|
||||||
delete_database(self.path, clean_filename(name))
|
self.newbibles[number].session.close()
|
||||||
del self.newbibles[number]
|
del self.newbibles[number]
|
||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||||
(number + 1, self.maxBibles, name),
|
(number + 1, max_bibles, name),
|
||||||
self.progressBar.maximum() - self.progressBar.value())
|
self.progressBar.maximum() - self.progressBar.value())
|
||||||
number += 1
|
self.success[number] = False
|
||||||
continue
|
continue
|
||||||
self.progressBar.setMaximum(len(books))
|
self.progressBar.setMaximum(len(books))
|
||||||
for book in books:
|
for book in books:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\n'
|
'Upgrading Bible %s of %s: "%s"\n'
|
||||||
'Upgrading %s ...')) %
|
'Upgrading %s ...')) %
|
||||||
(number + 1, self.maxBibles, name, book))
|
(number + 1, max_bibles, name, book))
|
||||||
book_ref_id = self.newbibles[number].\
|
book_ref_id = self.newbibles[number].\
|
||||||
get_book_ref_id_by_name(book, len(books), language_id)
|
get_book_ref_id_by_name(book, len(books), language_id)
|
||||||
if not book_ref_id:
|
if not book_ref_id:
|
||||||
@ -647,24 +487,24 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
u'name: "%s" aborted by user' % (
|
u'name: "%s" aborted by user' % (
|
||||||
meta_data[u'download source'],
|
meta_data[u'download source'],
|
||||||
meta_data[u'download name']))
|
meta_data[u'download name']))
|
||||||
delete_database(self.path, clean_filename(name))
|
self.newbibles[number].session.close()
|
||||||
del self.newbibles[number]
|
del self.newbibles[number]
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||||
db_book = self.newbibles[number].create_book(book,
|
db_book = self.newbibles[number].create_book(book,
|
||||||
book_ref_id, book_details[u'testament_id'])
|
book_ref_id, book_details[u'testament_id'])
|
||||||
# Try to import still downloaded verses
|
# Try to import already downloaded verses.
|
||||||
oldbook = oldbible.get_book(book)
|
oldbook = oldBible.get_book(book)
|
||||||
if oldbook:
|
if oldbook:
|
||||||
verses = oldbible.get_verses(oldbook[u'id'])
|
verses = oldBible.get_verses(oldbook[u'id'])
|
||||||
if not verses:
|
if not verses:
|
||||||
log.warn(u'No verses found to import for book '
|
log.warn(u'No verses found to import for book '
|
||||||
u'"%s"', book)
|
u'"%s"', book)
|
||||||
continue
|
continue
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
self.newbibles[number].create_verse(db_book.id,
|
self.newbibles[number].create_verse(db_book.id,
|
||||||
int(verse[u'chapter']),
|
int(verse[u'chapter']),
|
||||||
@ -678,40 +518,40 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
language_id = self.newbibles[number].get_language(name)
|
language_id = self.newbibles[number].get_language(name)
|
||||||
if not language_id:
|
if not language_id:
|
||||||
log.warn(u'Upgrading books from "%s" failed' % name)
|
log.warn(u'Upgrading books from "%s" failed' % name)
|
||||||
delete_database(self.path, clean_filename(name))
|
self.newbibles[number].session.close()
|
||||||
del self.newbibles[number]
|
del self.newbibles[number]
|
||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||||
(number + 1, self.maxBibles, name),
|
(number + 1, max_bibles, name),
|
||||||
self.progressBar.maximum() - self.progressBar.value())
|
self.progressBar.maximum() - self.progressBar.value())
|
||||||
number += 1
|
self.success[number] = False
|
||||||
continue
|
continue
|
||||||
books = oldbible.get_books()
|
books = oldBible.get_books()
|
||||||
self.progressBar.setMaximum(len(books))
|
self.progressBar.setMaximum(len(books))
|
||||||
for book in books:
|
for book in books:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\n'
|
'Upgrading Bible %s of %s: "%s"\n'
|
||||||
'Upgrading %s ...')) %
|
'Upgrading %s ...')) %
|
||||||
(number + 1, self.maxBibles, name, book[u'name']))
|
(number + 1, max_bibles, name, book[u'name']))
|
||||||
book_ref_id = self.newbibles[number].\
|
book_ref_id = self.newbibles[number].\
|
||||||
get_book_ref_id_by_name(book[u'name'], len(books),
|
get_book_ref_id_by_name(book[u'name'], len(books),
|
||||||
language_id)
|
language_id)
|
||||||
if not book_ref_id:
|
if not book_ref_id:
|
||||||
log.warn(u'Upgrading books from %s " '\
|
log.warn(u'Upgrading books from %s " '\
|
||||||
'failed - aborted by user' % name)
|
'failed - aborted by user' % name)
|
||||||
delete_database(self.path, clean_filename(name))
|
self.newbibles[number].session.close()
|
||||||
del self.newbibles[number]
|
del self.newbibles[number]
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||||
db_book = self.newbibles[number].create_book(book[u'name'],
|
db_book = self.newbibles[number].create_book(book[u'name'],
|
||||||
book_ref_id, book_details[u'testament_id'])
|
book_ref_id, book_details[u'testament_id'])
|
||||||
verses = oldbible.get_verses(book[u'id'])
|
verses = oldBible.get_verses(book[u'id'])
|
||||||
if not verses:
|
if not verses:
|
||||||
log.warn(u'No verses found to import for book '
|
log.warn(u'No verses found to import for book '
|
||||||
u'"%s"', book[u'name'])
|
u'"%s"', book[u'name'])
|
||||||
@ -719,31 +559,32 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
continue
|
continue
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
bible_failed = True
|
self.success[number] = False
|
||||||
break
|
break
|
||||||
self.newbibles[number].create_verse(db_book.id,
|
self.newbibles[number].create_verse(db_book.id,
|
||||||
int(verse[u'chapter']),
|
int(verse[u'chapter']),
|
||||||
int(verse[u'verse']), unicode(verse[u'text']))
|
int(verse[u'verse']), unicode(verse[u'text']))
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
self.newbibles[number].session.commit()
|
self.newbibles[number].session.commit()
|
||||||
if not bible_failed:
|
if self.success.has_key(number) and not self.success[number]:
|
||||||
|
self.incrementProgressBar(unicode(translate(
|
||||||
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
|
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||||
|
(number + 1, max_bibles, name),
|
||||||
|
self.progressBar.maximum() - self.progressBar.value())
|
||||||
|
else:
|
||||||
|
self.success[number] = True
|
||||||
self.newbibles[number].create_meta(u'Version', name)
|
self.newbibles[number].create_meta(u'Version', name)
|
||||||
oldbible.close_connection()
|
|
||||||
delete_file(os.path.join(self.path, filename[0]))
|
|
||||||
self.incrementProgressBar(unicode(translate(
|
self.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
'Upgrading Bible %s of %s: "%s"\n'
|
'Upgrading Bible %s of %s: "%s"\n'
|
||||||
'Complete')) %
|
'Complete')) %
|
||||||
(number + 1, self.maxBibles, name))
|
(number + 1, max_bibles, name))
|
||||||
self.success[biblenumber] = True
|
if self.newbibles.has_key(number):
|
||||||
else:
|
self.newbibles[number].session.close()
|
||||||
self.incrementProgressBar(unicode(translate(
|
# Close the last bible's connection if possible.
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
if oldBible is not None:
|
||||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
oldBible.close_connection()
|
||||||
(number + 1, self.maxBibles, name),
|
|
||||||
self.progressBar.maximum() - self.progressBar.value())
|
|
||||||
delete_database(self.path, clean_filename(name))
|
|
||||||
number += 1
|
|
||||||
|
|
||||||
def postWizard(self):
|
def postWizard(self):
|
||||||
"""
|
"""
|
||||||
@ -752,10 +593,14 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
successful_import = 0
|
successful_import = 0
|
||||||
failed_import = 0
|
failed_import = 0
|
||||||
for number, filename in enumerate(self.files):
|
for number, filename in enumerate(self.files):
|
||||||
if number in self.success and self.success[number] == True:
|
if self.success.has_key(number) and self.success[number]:
|
||||||
successful_import += 1
|
successful_import += 1
|
||||||
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||||
failed_import += 1
|
failed_import += 1
|
||||||
|
# Delete upgraded (but not complete, corrupted, ...) bible.
|
||||||
|
delete_file(os.path.join(self.path, filename[0]))
|
||||||
|
# Copy not upgraded bible back.
|
||||||
|
shutil.move(os.path.join(self.temp_dir, filename[0]), self.path)
|
||||||
if failed_import > 0:
|
if failed_import > 0:
|
||||||
failed_import_text = unicode(translate(
|
failed_import_text = unicode(translate(
|
||||||
'BiblesPlugin.UpgradeWizardForm',
|
'BiblesPlugin.UpgradeWizardForm',
|
||||||
@ -776,7 +621,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||||||
'Bible(s): %s successful%s')) % (successful_import,
|
'Bible(s): %s successful%s')) % (successful_import,
|
||||||
failed_import_text))
|
failed_import_text))
|
||||||
else:
|
else:
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(translate(
|
||||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
|
'BiblesPlugin.UpgradeWizardForm', 'Upgrade failed.'))
|
||||||
'failed.'))
|
# Remove temp directory.
|
||||||
|
shutil.rmtree(self.temp_dir, True)
|
||||||
OpenLPWizard.postWizard(self)
|
OpenLPWizard.postWizard(self)
|
||||||
|
@ -44,8 +44,8 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
|||||||
Class to manage a dialog which ask the user for a language.
|
Class to manage a dialog which ask the user for a language.
|
||||||
"""
|
"""
|
||||||
log.info(u'LanguageForm loaded')
|
log.info(u'LanguageForm loaded')
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
def __init__(self, parent=None):
|
||||||
"""
|
"""
|
||||||
Constructor
|
Constructor
|
||||||
"""
|
"""
|
||||||
@ -57,12 +57,11 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
|||||||
if bible_name:
|
if bible_name:
|
||||||
self.bibleLabel.setText(unicode(bible_name))
|
self.bibleLabel.setText(unicode(bible_name))
|
||||||
items = BiblesResourcesDB.get_languages()
|
items = BiblesResourcesDB.get_languages()
|
||||||
for item in items:
|
self.languageComboBox.addItems([item[u'name'] for item in items])
|
||||||
self.languageComboBox.addItem(item[u'name'])
|
|
||||||
return QDialog.exec_(self)
|
return QDialog.exec_(self)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
if self.languageComboBox.currentText() == u'':
|
if not self.languageComboBox.currentText():
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
message=translate('BiblesPlugin.LanguageForm',
|
message=translate('BiblesPlugin.LanguageForm',
|
||||||
'You need to choose a language.'))
|
'You need to choose a language.'))
|
||||||
|
@ -39,7 +39,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
|
|||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation, clean_filename
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -63,19 +63,6 @@ class Verse(BaseModel):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clean_filename(filename):
|
|
||||||
"""
|
|
||||||
Clean up the version name of the Bible and convert it into a valid
|
|
||||||
file name.
|
|
||||||
|
|
||||||
``filename``
|
|
||||||
The "dirty" file name or version name.
|
|
||||||
"""
|
|
||||||
if not isinstance(filename, unicode):
|
|
||||||
filename = unicode(filename, u'utf-8')
|
|
||||||
filename = re.sub(r'[^\w]+', u'_', filename).strip(u'_')
|
|
||||||
return filename + u'.sqlite'
|
|
||||||
|
|
||||||
def init_schema(url):
|
def init_schema(url):
|
||||||
"""
|
"""
|
||||||
Setup a bible database connection and initialise the database schema.
|
Setup a bible database connection and initialise the database schema.
|
||||||
@ -158,7 +145,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||||||
self.name = kwargs[u'name']
|
self.name = kwargs[u'name']
|
||||||
if not isinstance(self.name, unicode):
|
if not isinstance(self.name, unicode):
|
||||||
self.name = unicode(self.name, u'utf-8')
|
self.name = unicode(self.name, u'utf-8')
|
||||||
self.file = clean_filename(self.name)
|
self.file = clean_filename(self.name) + u'.sqlite'
|
||||||
if u'file' in kwargs:
|
if u'file' in kwargs:
|
||||||
self.file = kwargs[u'file']
|
self.file = kwargs[u'file']
|
||||||
Manager.__init__(self, u'bibles', init_schema, self.file)
|
Manager.__init__(self, u'bibles', init_schema, self.file)
|
||||||
@ -210,7 +197,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||||||
The book_reference_id from bibles_resources.sqlite of the book.
|
The book_reference_id from bibles_resources.sqlite of the book.
|
||||||
|
|
||||||
``testament``
|
``testament``
|
||||||
*Defaults to 1.* The testament_reference_id from
|
*Defaults to 1.* The testament_reference_id from
|
||||||
bibles_resources.sqlite of the testament this book belongs to.
|
bibles_resources.sqlite of the testament this book belongs to.
|
||||||
"""
|
"""
|
||||||
log.debug(u'BibleDB.create_book("%s", "%s")', name, bk_ref_id)
|
log.debug(u'BibleDB.create_book("%s", "%s")', name, bk_ref_id)
|
||||||
@ -329,7 +316,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||||||
return self.get_object_filtered(Book, Book.book_reference_id.like(id))
|
return self.get_object_filtered(Book, Book.book_reference_id.like(id))
|
||||||
|
|
||||||
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
||||||
log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book,
|
log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book,
|
||||||
language_id)
|
language_id)
|
||||||
if BiblesResourcesDB.get_book(book, True):
|
if BiblesResourcesDB.get_book(book, True):
|
||||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||||
@ -471,7 +458,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
def get_language(self, bible_name=None):
|
def get_language(self, bible_name=None):
|
||||||
"""
|
"""
|
||||||
If no language is given it calls a dialog window where the user could
|
If no language is given it calls a dialog window where the user could
|
||||||
select the bible language.
|
select the bible language.
|
||||||
Return the language id of a bible.
|
Return the language id of a bible.
|
||||||
|
|
||||||
@ -521,9 +508,9 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
some resources which are used in the Bibles plugin.
|
some resources which are used in the Bibles plugin.
|
||||||
A wrapper class around a small SQLite database which contains the download
|
A wrapper class around a small SQLite database which contains the download
|
||||||
resources, a biblelist from the different download resources, the books,
|
resources, a biblelist from the different download resources, the books,
|
||||||
chapter counts and verse counts for the web download Bibles, a language
|
chapter counts and verse counts for the web download Bibles, a language
|
||||||
reference, the testament reference and some alternative book names. This
|
reference, the testament reference and some alternative book names. This
|
||||||
class contains a singleton "cursor" so that only one connection to the
|
class contains a singleton "cursor" so that only one connection to the
|
||||||
SQLite database is ever used.
|
SQLite database is ever used.
|
||||||
"""
|
"""
|
||||||
cursor = None
|
cursor = None
|
||||||
@ -582,7 +569,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
``name``
|
``name``
|
||||||
The name or abbreviation of the book.
|
The name or abbreviation of the book.
|
||||||
|
|
||||||
``lower``
|
``lower``
|
||||||
True if the comparsion should be only lowercase
|
True if the comparsion should be only lowercase
|
||||||
"""
|
"""
|
||||||
@ -592,7 +579,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
if lower:
|
if lower:
|
||||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||||
u'abbreviation, chapters FROM book_reference WHERE '
|
u'abbreviation, chapters FROM book_reference WHERE '
|
||||||
u'LOWER(name) = ? OR LOWER(abbreviation) = ?',
|
u'LOWER(name) = ? OR LOWER(abbreviation) = ?',
|
||||||
(name.lower(), name.lower()))
|
(name.lower(), name.lower()))
|
||||||
else:
|
else:
|
||||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||||
@ -621,7 +608,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
if not isinstance(id, int):
|
if not isinstance(id, int):
|
||||||
id = int(id)
|
id = int(id)
|
||||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||||
u'abbreviation, chapters FROM book_reference WHERE id = ?',
|
u'abbreviation, chapters FROM book_reference WHERE id = ?',
|
||||||
(id, ))
|
(id, ))
|
||||||
if books:
|
if books:
|
||||||
return {
|
return {
|
||||||
@ -645,12 +632,12 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
``chapter``
|
``chapter``
|
||||||
The chapter number.
|
The chapter number.
|
||||||
"""
|
"""
|
||||||
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id,
|
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id,
|
||||||
chapter)
|
chapter)
|
||||||
if not isinstance(chapter, int):
|
if not isinstance(chapter, int):
|
||||||
chapter = int(chapter)
|
chapter = int(chapter)
|
||||||
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
|
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
|
||||||
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
|
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
|
||||||
(book_id,))
|
(book_id,))
|
||||||
if chapters:
|
if chapters:
|
||||||
return {
|
return {
|
||||||
@ -687,7 +674,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
``chapter``
|
``chapter``
|
||||||
The number of the chapter.
|
The number of the chapter.
|
||||||
"""
|
"""
|
||||||
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,
|
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,
|
||||||
chapter)
|
chapter)
|
||||||
details = BiblesResourcesDB.get_chapter(book_id, chapter)
|
details = BiblesResourcesDB.get_chapter(book_id, chapter)
|
||||||
if details:
|
if details:
|
||||||
@ -715,7 +702,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_webbibles(source):
|
def get_webbibles(source):
|
||||||
"""
|
"""
|
||||||
@ -737,7 +724,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
u'id': bible[0],
|
u'id': bible[0],
|
||||||
u'name': bible[1],
|
u'name': bible[1],
|
||||||
u'abbreviation': bible[2],
|
u'abbreviation': bible[2],
|
||||||
u'language_id': bible[3],
|
u'language_id': bible[3],
|
||||||
u'download_source_id': bible[4]
|
u'download_source_id': bible[4]
|
||||||
}
|
}
|
||||||
for bible in bibles
|
for bible in bibles
|
||||||
@ -752,11 +739,11 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
``abbreviation``
|
``abbreviation``
|
||||||
The abbreviation of the webbible.
|
The abbreviation of the webbible.
|
||||||
|
|
||||||
``source``
|
``source``
|
||||||
The source of the webbible.
|
The source of the webbible.
|
||||||
"""
|
"""
|
||||||
log.debug(u'BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation,
|
log.debug(u'BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation,
|
||||||
source)
|
source)
|
||||||
if not isinstance(abbreviation, unicode):
|
if not isinstance(abbreviation, unicode):
|
||||||
abbreviation = unicode(abbreviation)
|
abbreviation = unicode(abbreviation)
|
||||||
@ -765,14 +752,14 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
source = BiblesResourcesDB.get_download_source(source)
|
source = BiblesResourcesDB.get_download_source(source)
|
||||||
bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
|
bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
|
||||||
u'language_id, download_source_id FROM webbibles WHERE '
|
u'language_id, download_source_id FROM webbibles WHERE '
|
||||||
u'download_source_id = ? AND abbreviation = ?', (source[u'id'],
|
u'download_source_id = ? AND abbreviation = ?', (source[u'id'],
|
||||||
abbreviation))
|
abbreviation))
|
||||||
if bible:
|
if bible:
|
||||||
return {
|
return {
|
||||||
u'id': bible[0][0],
|
u'id': bible[0][0],
|
||||||
u'name': bible[0][1],
|
u'name': bible[0][1],
|
||||||
u'abbreviation': bible[0][2],
|
u'abbreviation': bible[0][2],
|
||||||
u'language_id': bible[0][3],
|
u'language_id': bible[0][3],
|
||||||
u'download_source_id': bible[0][4]
|
u'download_source_id': bible[0][4]
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
@ -785,11 +772,11 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
``name``
|
``name``
|
||||||
The name to search the id.
|
The name to search the id.
|
||||||
|
|
||||||
``language_id``
|
``language_id``
|
||||||
The language_id for which language should be searched
|
The language_id for which language should be searched
|
||||||
"""
|
"""
|
||||||
log.debug(u'BiblesResourcesDB.get_alternative_book_name("%s", "%s")',
|
log.debug(u'BiblesResourcesDB.get_alternative_book_name("%s", "%s")',
|
||||||
name, language_id)
|
name, language_id)
|
||||||
if language_id:
|
if language_id:
|
||||||
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
|
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
|
||||||
@ -806,7 +793,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_language(name):
|
def get_language(name):
|
||||||
"""
|
"""
|
||||||
Return a dict containing the language id, name and code by name or
|
Return a dict containing the language id, name and code by name or
|
||||||
abbreviation.
|
abbreviation.
|
||||||
|
|
||||||
``name``
|
``name``
|
||||||
@ -865,7 +852,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
||||||
"""
|
"""
|
||||||
This class represents a database-bound alternative book names system.
|
This class represents a database-bound alternative book names system.
|
||||||
"""
|
"""
|
||||||
cursor = None
|
cursor = None
|
||||||
conn = None
|
conn = None
|
||||||
@ -874,7 +861,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||||||
def get_cursor():
|
def get_cursor():
|
||||||
"""
|
"""
|
||||||
Return the cursor object. Instantiate one if it doesn't exist yet.
|
Return the cursor object. Instantiate one if it doesn't exist yet.
|
||||||
If necessary loads up the database and creates the tables if the
|
If necessary loads up the database and creates the tables if the
|
||||||
database doesn't exist.
|
database doesn't exist.
|
||||||
"""
|
"""
|
||||||
if AlternativeBookNamesDB.cursor is None:
|
if AlternativeBookNamesDB.cursor is None:
|
||||||
@ -904,7 +891,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
``parameters``
|
``parameters``
|
||||||
Any variable parameters to add to the query
|
Any variable parameters to add to the query
|
||||||
|
|
||||||
``commit``
|
``commit``
|
||||||
If a commit statement is necessary this should be True.
|
If a commit statement is necessary this should be True.
|
||||||
"""
|
"""
|
||||||
@ -921,11 +908,11 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
``name``
|
``name``
|
||||||
The name to search the id.
|
The name to search the id.
|
||||||
|
|
||||||
``language_id``
|
``language_id``
|
||||||
The language_id for which language should be searched
|
The language_id for which language should be searched
|
||||||
"""
|
"""
|
||||||
log.debug(u'AlternativeBookNamesDB.get_book_reference_id("%s", "%s")',
|
log.debug(u'AlternativeBookNamesDB.get_book_reference_id("%s", "%s")',
|
||||||
name, language_id)
|
name, language_id)
|
||||||
if language_id:
|
if language_id:
|
||||||
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
|
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
|
||||||
@ -962,11 +949,11 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
class OldBibleDB(QtCore.QObject, Manager):
|
class OldBibleDB(QtCore.QObject, Manager):
|
||||||
"""
|
"""
|
||||||
This class conects to the old bible databases to reimport them to the new
|
This class conects to the old bible databases to reimport them to the new
|
||||||
database scheme.
|
database scheme.
|
||||||
"""
|
"""
|
||||||
cursor = None
|
cursor = None
|
||||||
|
|
||||||
def __init__(self, parent, **kwargs):
|
def __init__(self, parent, **kwargs):
|
||||||
"""
|
"""
|
||||||
The constructor loads up the database and creates and initialises the
|
The constructor loads up the database and creates and initialises the
|
||||||
|
@ -151,9 +151,10 @@ class BibleManager(object):
|
|||||||
name = bible.get_name()
|
name = bible.get_name()
|
||||||
# Remove corrupted files.
|
# Remove corrupted files.
|
||||||
if name is None:
|
if name is None:
|
||||||
|
bible.session.close()
|
||||||
delete_file(os.path.join(self.path, filename))
|
delete_file(os.path.join(self.path, filename))
|
||||||
continue
|
continue
|
||||||
# Find old database versions
|
# Find old database versions.
|
||||||
if bible.is_old_database():
|
if bible.is_old_database():
|
||||||
self.old_bible_databases.append([filename, name])
|
self.old_bible_databases.append([filename, name])
|
||||||
bible.session.close()
|
bible.session.close()
|
||||||
@ -220,7 +221,7 @@ class BibleManager(object):
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
u'name': book.name,
|
u'name': book.name,
|
||||||
u'book_reference_id': book.book_reference_id,
|
u'book_reference_id': book.book_reference_id,
|
||||||
u'chapters': self.db_cache[bible].get_chapter_count(book)
|
u'chapters': self.db_cache[bible].get_chapter_count(book)
|
||||||
}
|
}
|
||||||
for book in self.db_cache[bible].get_books()
|
for book in self.db_cache[bible].get_books()
|
||||||
@ -229,10 +230,10 @@ class BibleManager(object):
|
|||||||
def get_chapter_count(self, bible, book):
|
def get_chapter_count(self, bible, book):
|
||||||
"""
|
"""
|
||||||
Returns the number of Chapters for a given book.
|
Returns the number of Chapters for a given book.
|
||||||
|
|
||||||
``bible``
|
``bible``
|
||||||
Unicode. The Bible to get the list of books from.
|
Unicode. The Bible to get the list of books from.
|
||||||
|
|
||||||
``book``
|
``book``
|
||||||
The book object to get the chapter count for.
|
The book object to get the chapter count for.
|
||||||
"""
|
"""
|
||||||
@ -295,7 +296,7 @@ class BibleManager(object):
|
|||||||
if db_book:
|
if db_book:
|
||||||
book_id = db_book.book_reference_id
|
book_id = db_book.book_reference_id
|
||||||
log.debug(u'Book name corrected to "%s"', db_book.name)
|
log.debug(u'Book name corrected to "%s"', db_book.name)
|
||||||
new_reflist.append((book_id, item[1], item[2],
|
new_reflist.append((book_id, item[1], item[2],
|
||||||
item[3]))
|
item[3]))
|
||||||
else:
|
else:
|
||||||
log.debug(u'OpenLP failed to find book %s', item[0])
|
log.debug(u'OpenLP failed to find book %s', item[0])
|
||||||
|
@ -613,7 +613,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
if restore:
|
if restore:
|
||||||
old_text = unicode(combo.currentText())
|
old_text = unicode(combo.currentText())
|
||||||
combo.clear()
|
combo.clear()
|
||||||
combo.addItems([unicode(i) for i in range(range_from, range_to + 1)])
|
combo.addItems(map(unicode, range(range_from, range_to + 1)))
|
||||||
if restore and combo.findText(old_text) != -1:
|
if restore and combo.findText(old_text) != -1:
|
||||||
combo.setCurrentIndex(combo.findText(old_text))
|
combo.setCurrentIndex(combo.findText(old_text))
|
||||||
|
|
||||||
|
Binary file not shown.
@ -217,8 +217,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
for item in self.listView.selectedIndexes()]
|
for item in self.listView.selectedIndexes()]
|
||||||
for id in id_list:
|
for id in id_list:
|
||||||
self.plugin.manager.delete_object(CustomSlide, id)
|
self.plugin.manager.delete_object(CustomSlide, id)
|
||||||
for row in row_list:
|
self.onSearchTextButtonClick()
|
||||||
self.listView.takeItem(row)
|
|
||||||
|
|
||||||
def onFocus(self):
|
def onFocus(self):
|
||||||
self.searchTextEdit.setFocus()
|
self.searchTextEdit.setFocus()
|
||||||
|
@ -25,10 +25,13 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
|
||||||
from openlp.plugins.images.lib import ImageMediaItem
|
Receiver
|
||||||
|
from openlp.plugins.images.lib import ImageMediaItem, ImageTab
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,10 +39,13 @@ class ImagePlugin(Plugin):
|
|||||||
log.info(u'Image Plugin loaded')
|
log.info(u'Image Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem)
|
Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem,
|
||||||
|
ImageTab)
|
||||||
self.weight = -7
|
self.weight = -7
|
||||||
self.icon_path = u':/plugins/plugin_images.png'
|
self.icon_path = u':/plugins/plugin_images.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'image_updated'), self.image_updated)
|
||||||
|
|
||||||
def about(self):
|
def about(self):
|
||||||
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
|
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
|
||||||
@ -81,3 +87,13 @@ class ImagePlugin(Plugin):
|
|||||||
'Add the selected image to the service.')
|
'Add the selected image to the service.')
|
||||||
}
|
}
|
||||||
self.setPluginUiTextStrings(tooltips)
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
||||||
|
def image_updated(self):
|
||||||
|
"""
|
||||||
|
Triggered by saving and changing the image border. Sets the images in
|
||||||
|
image manager to require updates. Actual update is triggered by the
|
||||||
|
last part of saving the config.
|
||||||
|
"""
|
||||||
|
background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
|
||||||
|
+ u'/background color', QtCore.QVariant(u'#000000')))
|
||||||
|
self.liveController.imageManager.update_images(u'image', background)
|
||||||
|
@ -26,3 +26,4 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from mediaitem import ImageMediaItem
|
from mediaitem import ImageMediaItem
|
||||||
|
from imagetab import ImageTab
|
||||||
|
101
openlp/plugins/images/lib/imagetab.py
Normal file
101
openlp/plugins/images/lib/imagetab.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||||
|
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||||
|
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib import SettingsTab, translate, Receiver
|
||||||
|
from openlp.core.lib.ui import UiStrings, create_valign_combo
|
||||||
|
|
||||||
|
class ImageTab(SettingsTab):
|
||||||
|
"""
|
||||||
|
ImageTab is the images settings tab in the settings dialog.
|
||||||
|
"""
|
||||||
|
def __init__(self, parent, name, visible_title, icon_path):
|
||||||
|
SettingsTab.__init__(self, parent, name, visible_title, icon_path)
|
||||||
|
|
||||||
|
def setupUi(self):
|
||||||
|
self.setObjectName(u'ImagesTab')
|
||||||
|
SettingsTab.setupUi(self)
|
||||||
|
self.bgColorGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
|
self.bgColorGroupBox.setObjectName(u'FontGroupBox')
|
||||||
|
self.formLayout = QtGui.QFormLayout(self.bgColorGroupBox)
|
||||||
|
self.formLayout.setObjectName(u'FormLayout')
|
||||||
|
self.colorLayout = QtGui.QHBoxLayout()
|
||||||
|
self.backgroundColorLabel = QtGui.QLabel(self.bgColorGroupBox)
|
||||||
|
self.backgroundColorLabel.setObjectName(u'BackgroundColorLabel')
|
||||||
|
self.colorLayout.addWidget(self.backgroundColorLabel)
|
||||||
|
self.backgroundColorButton = QtGui.QPushButton(self.bgColorGroupBox)
|
||||||
|
self.backgroundColorButton.setObjectName(u'BackgroundColorButton')
|
||||||
|
self.colorLayout.addWidget(self.backgroundColorButton)
|
||||||
|
self.formLayout.addRow(self.colorLayout)
|
||||||
|
self.informationLabel = QtGui.QLabel(self.bgColorGroupBox)
|
||||||
|
self.informationLabel.setObjectName(u'InformationLabel')
|
||||||
|
self.formLayout.addRow(self.informationLabel)
|
||||||
|
self.leftLayout.addWidget(self.bgColorGroupBox)
|
||||||
|
self.leftLayout.addStretch()
|
||||||
|
self.rightColumn.setSizePolicy(
|
||||||
|
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
|
||||||
|
self.rightLayout.addStretch()
|
||||||
|
# Signals and slots
|
||||||
|
QtCore.QObject.connect(self.backgroundColorButton,
|
||||||
|
QtCore.SIGNAL(u'pressed()'), self.onbackgroundColorButtonClicked)
|
||||||
|
|
||||||
|
def retranslateUi(self):
|
||||||
|
self.bgColorGroupBox.setTitle(
|
||||||
|
translate('ImagesPlugin.ImageTab', 'Background Color'))
|
||||||
|
self.backgroundColorLabel.setText(
|
||||||
|
translate('ImagesPlugin.ImageTab', 'Default Color:'))
|
||||||
|
self.informationLabel.setText(
|
||||||
|
translate('ImagesPlugin.ImageTab', 'Provides border where image '
|
||||||
|
'is not the correct dimensions for the screen when resized.'))
|
||||||
|
|
||||||
|
def onbackgroundColorButtonClicked(self):
|
||||||
|
new_color = QtGui.QColorDialog.getColor(
|
||||||
|
QtGui.QColor(self.bg_color), self)
|
||||||
|
if new_color.isValid():
|
||||||
|
self.bg_color = new_color.name()
|
||||||
|
self.backgroundColorButton.setStyleSheet(
|
||||||
|
u'background-color: %s' % self.bg_color)
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
settings.beginGroup(self.settingsSection)
|
||||||
|
self.bg_color = unicode(settings.value(
|
||||||
|
u'background color', QtCore.QVariant(u'#000000')).toString())
|
||||||
|
self.initial_color = self.bg_color
|
||||||
|
settings.endGroup()
|
||||||
|
self.backgroundColorButton.setStyleSheet(
|
||||||
|
u'background-color: %s' % self.bg_color)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
settings.beginGroup(self.settingsSection)
|
||||||
|
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
||||||
|
settings.endGroup()
|
||||||
|
if self.initial_color != self.bg_color:
|
||||||
|
Receiver.send_message(u'image_updated')
|
||||||
|
|
@ -140,6 +140,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
self.plugin.formparent.finishedProgressBar()
|
self.plugin.formparent.finishedProgressBar()
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||||
|
background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
|
||||||
|
+ u'/background color', QtCore.QVariant(u'#000000')))
|
||||||
if item:
|
if item:
|
||||||
items = [item]
|
items = [item]
|
||||||
else:
|
else:
|
||||||
@ -183,7 +185,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
for bitem in items:
|
for bitem in items:
|
||||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||||
(path, name) = os.path.split(filename)
|
(path, name) = os.path.split(filename)
|
||||||
service_item.add_from_image(filename, name)
|
service_item.add_from_image(filename, name, background)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def onResetClick(self):
|
def onResetClick(self):
|
||||||
@ -206,13 +208,16 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
if check_item_selected(self.listView,
|
if check_item_selected(self.listView,
|
||||||
translate('ImagePlugin.MediaItem',
|
translate('ImagePlugin.MediaItem',
|
||||||
'You must select an image to replace the background with.')):
|
'You must select an image to replace the background with.')):
|
||||||
|
background = QtGui.QColor(QtCore.QSettings().value(
|
||||||
|
self.settingsSection + u'/background color',
|
||||||
|
QtCore.QVariant(u'#000000')))
|
||||||
item = self.listView.selectedIndexes()[0]
|
item = self.listView.selectedIndexes()[0]
|
||||||
bitem = self.listView.item(item.row())
|
bitem = self.listView.item(item.row())
|
||||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
(path, name) = os.path.split(filename)
|
(path, name) = os.path.split(filename)
|
||||||
if self.plugin.liveController.display.directImage(name,
|
if self.plugin.liveController.display.directImage(name,
|
||||||
filename):
|
filename, background):
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings().LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
|
@ -170,8 +170,8 @@ class SongExportForm(OpenLPWizard):
|
|||||||
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
|
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
|
||||||
self.informationLabel.setText(
|
self.informationLabel.setText(
|
||||||
translate('SongsPlugin.ExportWizardForm', 'This wizard will help to'
|
translate('SongsPlugin.ExportWizardForm', 'This wizard will help to'
|
||||||
' export your songs to the open and free OpenLyrics worship song '
|
' export your songs to the open and free <strong>OpenLyrics'
|
||||||
'format.'))
|
'</strong> worship song format.'))
|
||||||
self.availableSongsPage.setTitle(
|
self.availableSongsPage.setTitle(
|
||||||
translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
||||||
self.availableSongsPage.setSubTitle(
|
self.availableSongsPage.setSubTitle(
|
||||||
@ -285,7 +285,9 @@ class SongExportForm(OpenLPWizard):
|
|||||||
self, songs, unicode(self.directoryLineEdit.text()))
|
self, songs, unicode(self.directoryLineEdit.text()))
|
||||||
if exporter.do_export():
|
if exporter.do_export():
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(
|
||||||
translate('SongsPlugin.SongExportForm', 'Finished export.'))
|
translate('SongsPlugin.SongExportForm', 'Finished export. To '
|
||||||
|
'import these files use the <strong>OpenLyrics</strong> '
|
||||||
|
'importer.'))
|
||||||
else:
|
else:
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(
|
||||||
translate('SongsPlugin.SongExportForm',
|
translate('SongsPlugin.SongExportForm',
|
||||||
|
@ -31,6 +31,7 @@ the Songs plugin
|
|||||||
|
|
||||||
from sqlalchemy import Column, ForeignKey, Table, types
|
from sqlalchemy import Column, ForeignKey, Table, types
|
||||||
from sqlalchemy.orm import mapper, relation
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
from sqlalchemy.sql.expression import func
|
||||||
|
|
||||||
from openlp.core.lib.db import BaseModel, init_db
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
|
|
||||||
@ -70,7 +71,6 @@ class Topic(BaseModel):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def init_schema(url):
|
def init_schema(url):
|
||||||
"""
|
"""
|
||||||
Setup the songs database connection and initialise the database schema.
|
Setup the songs database connection and initialise the database schema.
|
||||||
@ -111,10 +111,6 @@ def init_schema(url):
|
|||||||
* file_name
|
* file_name
|
||||||
* type
|
* type
|
||||||
|
|
||||||
**media_files_songs Table**
|
|
||||||
* media_file_id
|
|
||||||
* song_id
|
|
||||||
|
|
||||||
**song_books Table**
|
**song_books Table**
|
||||||
The *song_books* table holds a list of books that a congregation gets
|
The *song_books* table holds a list of books that a congregation gets
|
||||||
their songs from, or old hymnals now no longer used. This table has the
|
their songs from, or old hymnals now no longer used. This table has the
|
||||||
@ -162,7 +158,7 @@ def init_schema(url):
|
|||||||
|
|
||||||
# Definition of the "authors" table
|
# Definition of the "authors" table
|
||||||
authors_table = Table(u'authors', metadata,
|
authors_table = Table(u'authors', metadata,
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
Column(u'first_name', types.Unicode(128)),
|
Column(u'first_name', types.Unicode(128)),
|
||||||
Column(u'last_name', types.Unicode(128)),
|
Column(u'last_name', types.Unicode(128)),
|
||||||
Column(u'display_name', types.Unicode(255), index=True, nullable=False)
|
Column(u'display_name', types.Unicode(255), index=True, nullable=False)
|
||||||
@ -170,22 +166,25 @@ def init_schema(url):
|
|||||||
|
|
||||||
# Definition of the "media_files" table
|
# Definition of the "media_files" table
|
||||||
media_files_table = Table(u'media_files', metadata,
|
media_files_table = Table(u'media_files', metadata,
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
|
Column(u'song_id', types.Integer(), ForeignKey(u'songs.id'),
|
||||||
|
default=None),
|
||||||
Column(u'file_name', types.Unicode(255), nullable=False),
|
Column(u'file_name', types.Unicode(255), nullable=False),
|
||||||
Column(u'type', types.Unicode(64), nullable=False, default=u'audio')
|
Column(u'type', types.Unicode(64), nullable=False, default=u'audio'),
|
||||||
|
Column(u'weight', types.Integer(), default=0)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definition of the "song_books" table
|
# Definition of the "song_books" table
|
||||||
song_books_table = Table(u'song_books', metadata,
|
song_books_table = Table(u'song_books', metadata,
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
Column(u'name', types.Unicode(128), nullable=False),
|
Column(u'name', types.Unicode(128), nullable=False),
|
||||||
Column(u'publisher', types.Unicode(128))
|
Column(u'publisher', types.Unicode(128))
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definition of the "songs" table
|
# Definition of the "songs" table
|
||||||
songs_table = Table(u'songs', metadata,
|
songs_table = Table(u'songs', metadata,
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
Column(u'song_book_id', types.Integer,
|
Column(u'song_book_id', types.Integer(),
|
||||||
ForeignKey(u'song_books.id'), default=None),
|
ForeignKey(u'song_books.id'), default=None),
|
||||||
Column(u'title', types.Unicode(255), nullable=False),
|
Column(u'title', types.Unicode(255), nullable=False),
|
||||||
Column(u'alternate_title', types.Unicode(255)),
|
Column(u'alternate_title', types.Unicode(255)),
|
||||||
@ -197,36 +196,31 @@ def init_schema(url):
|
|||||||
Column(u'song_number', types.Unicode(64)),
|
Column(u'song_number', types.Unicode(64)),
|
||||||
Column(u'theme_name', types.Unicode(128)),
|
Column(u'theme_name', types.Unicode(128)),
|
||||||
Column(u'search_title', types.Unicode(255), index=True, nullable=False),
|
Column(u'search_title', types.Unicode(255), index=True, nullable=False),
|
||||||
Column(u'search_lyrics', types.UnicodeText, nullable=False)
|
Column(u'search_lyrics', types.UnicodeText, nullable=False),
|
||||||
|
Column(u'create_date', types.DateTime(), default=func.now()),
|
||||||
|
Column(u'last_modified', types.DateTime(), default=func.now(),
|
||||||
|
onupdate=func.now())
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definition of the "topics" table
|
# Definition of the "topics" table
|
||||||
topics_table = Table(u'topics', metadata,
|
topics_table = Table(u'topics', metadata,
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
Column(u'name', types.Unicode(128), index=True, nullable=False)
|
Column(u'name', types.Unicode(128), index=True, nullable=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definition of the "authors_songs" table
|
# Definition of the "authors_songs" table
|
||||||
authors_songs_table = Table(u'authors_songs', metadata,
|
authors_songs_table = Table(u'authors_songs', metadata,
|
||||||
Column(u'author_id', types.Integer,
|
Column(u'author_id', types.Integer(),
|
||||||
ForeignKey(u'authors.id'), primary_key=True),
|
ForeignKey(u'authors.id'), primary_key=True),
|
||||||
Column(u'song_id', types.Integer,
|
Column(u'song_id', types.Integer(),
|
||||||
ForeignKey(u'songs.id'), primary_key=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "media_files_songs" table
|
|
||||||
media_files_songs_table = Table(u'media_files_songs', metadata,
|
|
||||||
Column(u'media_file_id', types.Integer,
|
|
||||||
ForeignKey(u'media_files.id'), primary_key=True),
|
|
||||||
Column(u'song_id', types.Integer,
|
|
||||||
ForeignKey(u'songs.id'), primary_key=True)
|
ForeignKey(u'songs.id'), primary_key=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Definition of the "songs_topics" table
|
# Definition of the "songs_topics" table
|
||||||
songs_topics_table = Table(u'songs_topics', metadata,
|
songs_topics_table = Table(u'songs_topics', metadata,
|
||||||
Column(u'song_id', types.Integer,
|
Column(u'song_id', types.Integer(),
|
||||||
ForeignKey(u'songs.id'), primary_key=True),
|
ForeignKey(u'songs.id'), primary_key=True),
|
||||||
Column(u'topic_id', types.Integer,
|
Column(u'topic_id', types.Integer(),
|
||||||
ForeignKey(u'topics.id'), primary_key=True)
|
ForeignKey(u'topics.id'), primary_key=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -238,8 +232,7 @@ def init_schema(url):
|
|||||||
'authors': relation(Author, backref='songs',
|
'authors': relation(Author, backref='songs',
|
||||||
secondary=authors_songs_table, lazy=False),
|
secondary=authors_songs_table, lazy=False),
|
||||||
'book': relation(Book, backref='songs'),
|
'book': relation(Book, backref='songs'),
|
||||||
'media_files': relation(MediaFile, backref='songs',
|
'media_files': relation(MediaFile, backref='songs'),
|
||||||
secondary=media_files_songs_table),
|
|
||||||
'topics': relation(Topic, backref='songs',
|
'topics': relation(Topic, backref='songs',
|
||||||
secondary=songs_topics_table)
|
secondary=songs_topics_table)
|
||||||
})
|
})
|
||||||
|
@ -35,6 +35,7 @@ import re
|
|||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from openlp.core.lib import check_directory_exists, Receiver, translate
|
from openlp.core.lib import check_directory_exists, Receiver, translate
|
||||||
|
from openlp.core.utils import clean_filename
|
||||||
from openlp.plugins.songs.lib import OpenLyrics
|
from openlp.plugins.songs.lib import OpenLyrics
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -72,8 +73,7 @@ class OpenLyricsExport(object):
|
|||||||
tree = etree.ElementTree(etree.fromstring(xml))
|
tree = etree.ElementTree(etree.fromstring(xml))
|
||||||
filename = u'%s (%s)' % (song.title,
|
filename = u'%s (%s)' % (song.title,
|
||||||
u', '.join([author.display_name for author in song.authors]))
|
u', '.join([author.display_name for author in song.authors]))
|
||||||
filename = re.sub(
|
filename = clean_filename(filename)
|
||||||
r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
|
|
||||||
# Ensure the filename isn't too long for some filesystems
|
# Ensure the filename isn't too long for some filesystems
|
||||||
filename = u'%s.xml' % filename[0:250 - len(self.save_path)]
|
filename = u'%s.xml' % filename[0:250 - len(self.save_path)]
|
||||||
# Pass a file object, because lxml does not cope with some special
|
# Pass a file object, because lxml does not cope with some special
|
||||||
|
@ -102,7 +102,6 @@ class SongShowPlusImport(SongImport):
|
|||||||
if not isinstance(self.import_source, list):
|
if not isinstance(self.import_source, list):
|
||||||
return
|
return
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
|
|
||||||
for file in self.import_source:
|
for file in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return
|
return
|
||||||
@ -113,7 +112,6 @@ class SongShowPlusImport(SongImport):
|
|||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
WizardStrings.ImportingType % file_name, 0)
|
||||||
songData = open(file, 'rb')
|
songData = open(file, 'rb')
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
blockKey, = struct.unpack("I", songData.read(4))
|
blockKey, = struct.unpack("I", songData.read(4))
|
||||||
# The file ends with 4 NUL's
|
# The file ends with 4 NUL's
|
||||||
@ -128,8 +126,9 @@ class SongShowPlusImport(SongImport):
|
|||||||
songData.read(2))
|
songData.read(2))
|
||||||
verseName = songData.read(verseNameLength)
|
verseName = songData.read(verseNameLength)
|
||||||
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
||||||
|
log.debug(lengthDescriptorSize)
|
||||||
# Detect if/how long the length descriptor is
|
# Detect if/how long the length descriptor is
|
||||||
if lengthDescriptorSize == 12:
|
if lengthDescriptorSize == 12 or lengthDescriptorSize == 20:
|
||||||
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
||||||
elif lengthDescriptorSize == 2:
|
elif lengthDescriptorSize == 2:
|
||||||
lengthDescriptor = 1
|
lengthDescriptor = 1
|
||||||
@ -137,6 +136,7 @@ class SongShowPlusImport(SongImport):
|
|||||||
lengthDescriptor = 0
|
lengthDescriptor = 0
|
||||||
else:
|
else:
|
||||||
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
||||||
|
log.debug(lengthDescriptorSize)
|
||||||
data = songData.read(lengthDescriptor)
|
data = songData.read(lengthDescriptor)
|
||||||
if blockKey == TITLE:
|
if blockKey == TITLE:
|
||||||
self.title = unicode(data, u'cp1252')
|
self.title = unicode(data, u'cp1252')
|
||||||
|
88
openlp/plugins/songs/lib/upgrade.py
Normal file
88
openlp/plugins/songs/lib/upgrade.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||||
|
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||||
|
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`upgrade` module provides a way for the database and schema that is the
|
||||||
|
backend for the Songs plugin
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import Column, ForeignKey, Table, types
|
||||||
|
from sqlalchemy.sql.expression import func
|
||||||
|
from migrate import changeset
|
||||||
|
from migrate.changeset.constraint import ForeignKeyConstraint
|
||||||
|
|
||||||
|
__version__ = 2
|
||||||
|
|
||||||
|
def upgrade_setup(metadata):
|
||||||
|
"""
|
||||||
|
Set up the latest revision all tables, with reflection, needed for the
|
||||||
|
upgrade process. If you want to drop a table, you need to remove it from
|
||||||
|
here, and add it to your upgrade function.
|
||||||
|
"""
|
||||||
|
tables = {
|
||||||
|
u'authors': Table(u'authors', metadata, autoload=True),
|
||||||
|
u'media_files': Table(u'media_files', metadata, autoload=True),
|
||||||
|
u'song_books': Table(u'song_books', metadata, autoload=True),
|
||||||
|
u'songs': Table(u'songs', metadata, autoload=True),
|
||||||
|
u'topics': Table(u'topics', metadata, autoload=True),
|
||||||
|
u'authors_songs': Table(u'authors_songs', metadata, autoload=True),
|
||||||
|
u'songs_topics': Table(u'songs_topics', metadata, autoload=True)
|
||||||
|
}
|
||||||
|
return tables
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_1(session, metadata, tables):
|
||||||
|
"""
|
||||||
|
Version 1 upgrade.
|
||||||
|
|
||||||
|
This upgrade removes the many-to-many relationship between songs and
|
||||||
|
media_files and replaces it with a one-to-many, which is far more
|
||||||
|
representative of the real relationship between the two entities.
|
||||||
|
|
||||||
|
In order to facilitate this one-to-many relationship, a song_id column is
|
||||||
|
added to the media_files table, and a weight column so that the media
|
||||||
|
files can be ordered.
|
||||||
|
"""
|
||||||
|
Table(u'media_files_songs', metadata, autoload=True).drop(checkfirst=True)
|
||||||
|
Column(u'song_id', types.Integer(), default=None)\
|
||||||
|
.create(table=tables[u'media_files'], populate_default=True)
|
||||||
|
Column(u'weight', types.Integer(), default=0)\
|
||||||
|
.create(table=tables[u'media_files'], populate_default=True)
|
||||||
|
if metadata.bind.url.get_dialect().name != 'sqlite':
|
||||||
|
# SQLite doesn't support ALTER TABLE ADD CONSTRAINT
|
||||||
|
ForeignKeyConstraint([u'song_id'], [u'songs.id'],
|
||||||
|
table=tables[u'media_files']).create()
|
||||||
|
|
||||||
|
def upgrade_2(session, metadata, tables):
|
||||||
|
"""
|
||||||
|
Version 2 upgrade.
|
||||||
|
|
||||||
|
This upgrade adds a create_date and last_modified date to the songs table
|
||||||
|
"""
|
||||||
|
Column(u'create_date', types.DateTime(), default=func.now())\
|
||||||
|
.create(table=tables[u'songs'], populate_default=True)
|
||||||
|
Column(u'last_modified', types.DateTime(), default=func.now())\
|
||||||
|
.create(table=tables[u'songs'], populate_default=True)
|
@ -246,8 +246,9 @@ class OpenLyrics(object):
|
|||||||
# Append the necessary meta data to the song.
|
# Append the necessary meta data to the song.
|
||||||
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
|
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
|
||||||
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
|
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
|
||||||
song_xml.set(u'createdIn', get_application_version()[u'version'])
|
application_name = u'OpenLP ' + get_application_version()[u'version']
|
||||||
song_xml.set(u'modifiedIn', get_application_version()[u'version'])
|
song_xml.set(u'createdIn', application_name)
|
||||||
|
song_xml.set(u'modifiedIn', application_name)
|
||||||
song_xml.set(u'modifiedDate',
|
song_xml.set(u'modifiedDate',
|
||||||
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
|
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
|
||||||
properties = etree.SubElement(song_xml, u'properties')
|
properties = etree.SubElement(song_xml, u'properties')
|
||||||
|
@ -36,7 +36,8 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
|
|||||||
from openlp.core.lib.db import Manager
|
from openlp.core.lib.db import Manager
|
||||||
from openlp.core.lib.ui import UiStrings, base_action, icon_action
|
from openlp.core.lib.ui import UiStrings, base_action, icon_action
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from openlp.plugins.songs.lib import clean_song, SongMediaItem, SongsTab
|
from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \
|
||||||
|
SongsTab
|
||||||
from openlp.plugins.songs.lib.db import init_schema, Song
|
from openlp.plugins.songs.lib.db import init_schema, Song
|
||||||
from openlp.plugins.songs.lib.importer import SongFormat
|
from openlp.plugins.songs.lib.importer import SongFormat
|
||||||
from openlp.plugins.songs.lib.olpimport import OpenLPSongImport
|
from openlp.plugins.songs.lib.olpimport import OpenLPSongImport
|
||||||
@ -58,8 +59,8 @@ class SongsPlugin(Plugin):
|
|||||||
Create and set up the Songs plugin.
|
Create and set up the Songs plugin.
|
||||||
"""
|
"""
|
||||||
Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab)
|
Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab)
|
||||||
|
self.manager = Manager(u'songs', init_schema, upgrade_mod=upgrade)
|
||||||
self.weight = -10
|
self.weight = -10
|
||||||
self.manager = Manager(u'songs', init_schema)
|
|
||||||
self.icon_path = u':/plugins/plugin_songs.png'
|
self.icon_path = u':/plugins/plugin_songs.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
|
||||||
|
@ -34,26 +34,33 @@ class Ui_SongUsageDeleteDialog(object):
|
|||||||
def setupUi(self, songUsageDeleteDialog):
|
def setupUi(self, songUsageDeleteDialog):
|
||||||
songUsageDeleteDialog.setObjectName(u'songUsageDeleteDialog')
|
songUsageDeleteDialog.setObjectName(u'songUsageDeleteDialog')
|
||||||
songUsageDeleteDialog.resize(291, 243)
|
songUsageDeleteDialog.resize(291, 243)
|
||||||
self.layoutWidget = QtGui.QWidget(songUsageDeleteDialog)
|
self.verticalLayout = QtGui.QVBoxLayout(songUsageDeleteDialog)
|
||||||
self.layoutWidget.setGeometry(QtCore.QRect(20, 10, 247, 181))
|
self.verticalLayout.setSpacing(8)
|
||||||
self.layoutWidget.setObjectName(u'layoutWidget')
|
self.verticalLayout.setContentsMargins(8, 8, 8, 8)
|
||||||
self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget)
|
|
||||||
self.verticalLayout.setObjectName(u'verticalLayout')
|
self.verticalLayout.setObjectName(u'verticalLayout')
|
||||||
self.deleteCalendar = QtGui.QCalendarWidget(self.layoutWidget)
|
self.deleteLabel = QtGui.QLabel(songUsageDeleteDialog)
|
||||||
|
self.deleteLabel.setObjectName(u'deleteLabel')
|
||||||
|
self.verticalLayout.addWidget(self.deleteLabel)
|
||||||
|
self.deleteCalendar = QtGui.QCalendarWidget(songUsageDeleteDialog)
|
||||||
self.deleteCalendar.setFirstDayOfWeek(QtCore.Qt.Sunday)
|
self.deleteCalendar.setFirstDayOfWeek(QtCore.Qt.Sunday)
|
||||||
self.deleteCalendar.setGridVisible(True)
|
self.deleteCalendar.setGridVisible(True)
|
||||||
self.deleteCalendar.setVerticalHeaderFormat(
|
self.deleteCalendar.setVerticalHeaderFormat(
|
||||||
QtGui.QCalendarWidget.NoVerticalHeader)
|
QtGui.QCalendarWidget.NoVerticalHeader)
|
||||||
self.deleteCalendar.setObjectName(u'deleteCalendar')
|
self.deleteCalendar.setObjectName(u'deleteCalendar')
|
||||||
self.verticalLayout.addWidget(self.deleteCalendar)
|
self.verticalLayout.addWidget(self.deleteCalendar)
|
||||||
self.buttonBox = create_accept_reject_button_box(
|
self.buttonBox = QtGui.QDialogButtonBox(songUsageDeleteDialog)
|
||||||
songUsageDeleteDialog, True)
|
self.buttonBox.setStandardButtons(
|
||||||
self.buttonBox.setGeometry(QtCore.QRect(30, 210, 245, 25))
|
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
|
||||||
self.buttonBox.setObjectName(u'buttonBox')
|
self.buttonBox.setObjectName(u'buttonBox')
|
||||||
|
self.verticalLayout.addWidget(self.buttonBox)
|
||||||
self.retranslateUi(songUsageDeleteDialog)
|
self.retranslateUi(songUsageDeleteDialog)
|
||||||
QtCore.QMetaObject.connectSlotsByName(songUsageDeleteDialog)
|
|
||||||
|
|
||||||
def retranslateUi(self, songUsageDeleteDialog):
|
def retranslateUi(self, songUsageDeleteDialog):
|
||||||
songUsageDeleteDialog.setWindowTitle(
|
songUsageDeleteDialog.setWindowTitle(
|
||||||
translate('SongUsagePlugin.SongUsageDeleteForm',
|
translate('SongUsagePlugin.SongUsageDeleteForm',
|
||||||
'Delete Song Usage Data'))
|
'Delete Song Usage Data'))
|
||||||
|
self.deleteLabel.setText(
|
||||||
|
translate('SongUsagePlugin.SongUsageDeleteForm',
|
||||||
|
'Select the date up to which the song usage data should be '
|
||||||
|
'deleted. All data recorded before this date will be '
|
||||||
|
'permanently deleted.'))
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate, Receiver
|
from openlp.core.lib import translate, Receiver
|
||||||
from openlp.plugins.songusage.lib.db import SongUsageItem
|
from openlp.plugins.songusage.lib.db import SongUsageItem
|
||||||
@ -42,23 +42,32 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
|
|||||||
self.manager = manager
|
self.manager = manager
|
||||||
QtGui.QDialog.__init__(self, parent)
|
QtGui.QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
QtCore.QObject.connect(
|
||||||
|
self.buttonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'),
|
||||||
|
self.onButtonBoxClicked)
|
||||||
|
|
||||||
def accept(self):
|
def onButtonBoxClicked(self, button):
|
||||||
ret = QtGui.QMessageBox.question(self,
|
if self.buttonBox.standardButton(button) == QtGui.QDialogButtonBox.Ok:
|
||||||
translate('SongUsagePlugin.SongUsageDeleteForm',
|
ret = QtGui.QMessageBox.question(self,
|
||||||
'Delete Selected Song Usage Events?'),
|
translate('SongUsagePlugin.SongUsageDeleteForm',
|
||||||
translate('SongUsagePlugin.SongUsageDeleteForm',
|
'Delete Selected Song Usage Events?'),
|
||||||
'Are you sure you want to delete selected Song Usage data?'),
|
translate('SongUsagePlugin.SongUsageDeleteForm',
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok |
|
'Are you sure you want to delete selected Song Usage '
|
||||||
QtGui.QMessageBox.Cancel),
|
'data?'),
|
||||||
QtGui.QMessageBox.Cancel)
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||||
if ret == QtGui.QMessageBox.Ok:
|
QtGui.QMessageBox.No),
|
||||||
deleteDate = self.deleteCalendar.selectedDate().toPyDate()
|
QtGui.QMessageBox.No)
|
||||||
self.manager.delete_all_objects(SongUsageItem,
|
if ret == QtGui.QMessageBox.Yes:
|
||||||
SongUsageItem.usagedate <= deleteDate)
|
deleteDate = self.deleteCalendar.selectedDate().toPyDate()
|
||||||
Receiver.send_message(u'openlp_information_message', {
|
self.manager.delete_all_objects(SongUsageItem,
|
||||||
u'title': translate('SongUsagePlugin.SongUsageDeleteForm',
|
SongUsageItem.usagedate <= deleteDate)
|
||||||
'Deletion Successful'),
|
Receiver.send_message(u'openlp_information_message', {
|
||||||
u'message': translate('SongUsagePlugin.SongUsageDeleteForm',
|
u'title': translate('SongUsagePlugin.SongUsageDeleteForm',
|
||||||
'All requested data has been deleted successfully. ')})
|
'Deletion Successful'),
|
||||||
self.close()
|
u'message': translate(
|
||||||
|
'SongUsagePlugin.SongUsageDeleteForm',
|
||||||
|
'All requested data has been deleted successfully. ')}
|
||||||
|
)
|
||||||
|
self.accept()
|
||||||
|
else:
|
||||||
|
self.reject()
|
||||||
|
@ -35,12 +35,14 @@ class Ui_SongUsageDetailDialog(object):
|
|||||||
songUsageDetailDialog.setObjectName(u'songUsageDetailDialog')
|
songUsageDetailDialog.setObjectName(u'songUsageDetailDialog')
|
||||||
songUsageDetailDialog.resize(609, 413)
|
songUsageDetailDialog.resize(609, 413)
|
||||||
self.verticalLayout = QtGui.QVBoxLayout(songUsageDetailDialog)
|
self.verticalLayout = QtGui.QVBoxLayout(songUsageDetailDialog)
|
||||||
|
self.verticalLayout.setSpacing(8)
|
||||||
|
self.verticalLayout.setContentsMargins(8, 8, 8, 8)
|
||||||
self.verticalLayout.setObjectName(u'verticalLayout')
|
self.verticalLayout.setObjectName(u'verticalLayout')
|
||||||
self.dateRangeGroupBox = QtGui.QGroupBox(songUsageDetailDialog)
|
self.dateRangeGroupBox = QtGui.QGroupBox(songUsageDetailDialog)
|
||||||
self.dateRangeGroupBox.setObjectName(u'dateRangeGroupBox')
|
self.dateRangeGroupBox.setObjectName(u'dateRangeGroupBox')
|
||||||
self.verticalLayout2 = QtGui.QVBoxLayout(self.dateRangeGroupBox)
|
self.dateHorizontalLayout = QtGui.QHBoxLayout(self.dateRangeGroupBox)
|
||||||
self.verticalLayout2.setObjectName(u'verticalLayout2')
|
self.dateHorizontalLayout.setSpacing(8)
|
||||||
self.dateHorizontalLayout = QtGui.QHBoxLayout()
|
self.dateHorizontalLayout.setContentsMargins(8, 8, 8, 8)
|
||||||
self.dateHorizontalLayout.setObjectName(u'dateHorizontalLayout')
|
self.dateHorizontalLayout.setObjectName(u'dateHorizontalLayout')
|
||||||
self.fromDate = QtGui.QCalendarWidget(self.dateRangeGroupBox)
|
self.fromDate = QtGui.QCalendarWidget(self.dateRangeGroupBox)
|
||||||
self.fromDate.setObjectName(u'fromDate')
|
self.fromDate.setObjectName(u'fromDate')
|
||||||
@ -53,26 +55,25 @@ class Ui_SongUsageDetailDialog(object):
|
|||||||
self.toDate = QtGui.QCalendarWidget(self.dateRangeGroupBox)
|
self.toDate = QtGui.QCalendarWidget(self.dateRangeGroupBox)
|
||||||
self.toDate.setObjectName(u'toDate')
|
self.toDate.setObjectName(u'toDate')
|
||||||
self.dateHorizontalLayout.addWidget(self.toDate)
|
self.dateHorizontalLayout.addWidget(self.toDate)
|
||||||
self.verticalLayout2.addLayout(self.dateHorizontalLayout)
|
self.verticalLayout.addWidget(self.dateRangeGroupBox)
|
||||||
self.fileGroupBox = QtGui.QGroupBox(self.dateRangeGroupBox)
|
self.fileGroupBox = QtGui.QGroupBox(self.dateRangeGroupBox)
|
||||||
self.fileGroupBox.setObjectName(u'fileGroupBox')
|
self.fileGroupBox.setObjectName(u'fileGroupBox')
|
||||||
self.verticalLayout4 = QtGui.QVBoxLayout(self.fileGroupBox)
|
self.fileHorizontalLayout = QtGui.QHBoxLayout(self.fileGroupBox)
|
||||||
self.verticalLayout4.setObjectName(u'verticalLayout4')
|
self.fileHorizontalLayout.setSpacing(8)
|
||||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
self.fileHorizontalLayout.setContentsMargins(8, 8, 8, 8)
|
||||||
self.horizontalLayout.setObjectName(u'horizontalLayout')
|
self.fileHorizontalLayout.setObjectName(u'fileHorizontalLayout')
|
||||||
self.fileLineEdit = QtGui.QLineEdit(self.fileGroupBox)
|
self.fileLineEdit = QtGui.QLineEdit(self.fileGroupBox)
|
||||||
self.fileLineEdit.setObjectName(u'fileLineEdit')
|
self.fileLineEdit.setObjectName(u'fileLineEdit')
|
||||||
self.fileLineEdit.setReadOnly(True)
|
self.fileLineEdit.setReadOnly(True)
|
||||||
self.fileLineEdit.setEnabled(False)
|
self.fileHorizontalLayout.addWidget(self.fileLineEdit)
|
||||||
self.horizontalLayout.addWidget(self.fileLineEdit)
|
|
||||||
self.saveFilePushButton = QtGui.QPushButton(self.fileGroupBox)
|
self.saveFilePushButton = QtGui.QPushButton(self.fileGroupBox)
|
||||||
|
self.saveFilePushButton.setMaximumWidth(
|
||||||
|
self.saveFilePushButton.size().height())
|
||||||
self.saveFilePushButton.setIcon(
|
self.saveFilePushButton.setIcon(
|
||||||
build_icon(u':/general/general_open.png'))
|
build_icon(u':/general/general_open.png'))
|
||||||
self.saveFilePushButton.setObjectName(u'saveFilePushButton')
|
self.saveFilePushButton.setObjectName(u'saveFilePushButton')
|
||||||
self.horizontalLayout.addWidget(self.saveFilePushButton)
|
self.fileHorizontalLayout.addWidget(self.saveFilePushButton)
|
||||||
self.verticalLayout4.addLayout(self.horizontalLayout)
|
self.verticalLayout.addWidget(self.fileGroupBox)
|
||||||
self.verticalLayout2.addWidget(self.fileGroupBox)
|
|
||||||
self.verticalLayout.addWidget(self.dateRangeGroupBox)
|
|
||||||
self.buttonBox = create_accept_reject_button_box(
|
self.buttonBox = create_accept_reject_button_box(
|
||||||
songUsageDetailDialog, True)
|
songUsageDetailDialog, True)
|
||||||
self.verticalLayout.addWidget(self.buttonBox)
|
self.verticalLayout.addWidget(self.buttonBox)
|
||||||
|
@ -117,9 +117,11 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
|
|||||||
try:
|
try:
|
||||||
fileHandle = open(outname, u'w')
|
fileHandle = open(outname, u'w')
|
||||||
for instance in usage:
|
for instance in usage:
|
||||||
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % (
|
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",' \
|
||||||
instance.usagedate, instance.usagetime, instance.title,
|
u'\"%s\",\"%s\"\n' % ( instance.usagedate,
|
||||||
instance.copyright, instance.ccl_number, instance.authors)
|
instance.usagetime, instance.title, instance.copyright,
|
||||||
|
instance.ccl_number, instance.authors,
|
||||||
|
instance.plugin_name, instance.source)
|
||||||
fileHandle.write(record.encode(u'utf-8'))
|
fileHandle.write(record.encode(u'utf-8'))
|
||||||
Receiver.send_message(u'openlp_information_message', {
|
Receiver.send_message(u'openlp_information_message', {
|
||||||
u'title': translate('SongUsagePlugin.SongUsageDetailForm',
|
u'title': translate('SongUsagePlugin.SongUsageDetailForm',
|
||||||
|
@ -56,7 +56,9 @@ def init_schema(url):
|
|||||||
Column(u'title', types.Unicode(255), nullable=False),
|
Column(u'title', types.Unicode(255), nullable=False),
|
||||||
Column(u'authors', types.Unicode(255), nullable=False),
|
Column(u'authors', types.Unicode(255), nullable=False),
|
||||||
Column(u'copyright', types.Unicode(255)),
|
Column(u'copyright', types.Unicode(255)),
|
||||||
Column(u'ccl_number', types.Unicode(65))
|
Column(u'ccl_number', types.Unicode(65)),
|
||||||
|
Column(u'plugin_name', types.Unicode(20)),
|
||||||
|
Column(u'source', types.Unicode(10))
|
||||||
)
|
)
|
||||||
|
|
||||||
mapper(SongUsageItem, songusage_table)
|
mapper(SongUsageItem, songusage_table)
|
||||||
|
58
openlp/plugins/songusage/lib/upgrade.py
Normal file
58
openlp/plugins/songusage/lib/upgrade.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||||
|
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||||
|
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`upgrade` module provides a way for the database and schema that is the
|
||||||
|
backend for the SongsUsage plugin
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import Column, Table, types
|
||||||
|
from migrate import changeset
|
||||||
|
|
||||||
|
__version__ = 1
|
||||||
|
|
||||||
|
def upgrade_setup(metadata):
|
||||||
|
"""
|
||||||
|
Set up the latest revision all tables, with reflection, needed for the
|
||||||
|
upgrade process. If you want to drop a table, you need to remove it from
|
||||||
|
here, and add it to your upgrade function.
|
||||||
|
"""
|
||||||
|
tables = {
|
||||||
|
u'songusage_data': Table(u'songusage_data', metadata, autoload=True)
|
||||||
|
}
|
||||||
|
return tables
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_1(session, metadata, tables):
|
||||||
|
"""
|
||||||
|
Version 1 upgrade.
|
||||||
|
|
||||||
|
This upgrade adds two new fields to the songusage database
|
||||||
|
"""
|
||||||
|
Column(u'plugin_name', types.Unicode(20), default=u'') \
|
||||||
|
.create(table=tables[u'songusage_data'], populate_default=True)
|
||||||
|
Column(u'source', types.Unicode(10), default=u'') \
|
||||||
|
.create(table=tables[u'songusage_data'], populate_default=True)
|
@ -37,6 +37,7 @@ from openlp.core.lib.ui import base_action, shortcut_action
|
|||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
||||||
SongUsageDeleteForm
|
SongUsageDeleteForm
|
||||||
|
from openlp.plugins.songusage.lib import upgrade
|
||||||
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
|
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -46,11 +47,11 @@ class SongUsagePlugin(Plugin):
|
|||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'songusage', plugin_helpers)
|
Plugin.__init__(self, u'songusage', plugin_helpers)
|
||||||
|
self.manager = Manager(u'songusage', init_schema, upgrade_mod=upgrade)
|
||||||
self.weight = -4
|
self.weight = -4
|
||||||
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
||||||
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
||||||
self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png')
|
self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png')
|
||||||
self.manager = None
|
|
||||||
self.songUsageActive = False
|
self.songUsageActive = False
|
||||||
|
|
||||||
def addToolsMenuItem(self, tools_menu):
|
def addToolsMenuItem(self, tools_menu):
|
||||||
@ -96,6 +97,7 @@ class SongUsagePlugin(Plugin):
|
|||||||
self.songUsageActiveButton = QtGui.QToolButton(
|
self.songUsageActiveButton = QtGui.QToolButton(
|
||||||
self.formparent.statusBar)
|
self.formparent.statusBar)
|
||||||
self.songUsageActiveButton.setCheckable(True)
|
self.songUsageActiveButton.setCheckable(True)
|
||||||
|
self.songUsageActiveButton.setAutoRaise(True)
|
||||||
self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin',
|
self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin',
|
||||||
'Toggle the tracking of song usage.'))
|
'Toggle the tracking of song usage.'))
|
||||||
self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
|
self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
|
||||||
@ -120,7 +122,10 @@ class SongUsagePlugin(Plugin):
|
|||||||
Plugin.initialise(self)
|
Plugin.initialise(self)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'slidecontroller_live_started'),
|
QtCore.SIGNAL(u'slidecontroller_live_started'),
|
||||||
self.onReceiveSongUsage)
|
self.displaySongUsage)
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'print_service_started'),
|
||||||
|
self.printSongUsage)
|
||||||
self.songUsageActive = QtCore.QSettings().value(
|
self.songUsageActive = QtCore.QSettings().value(
|
||||||
self.settingsSection + u'/active',
|
self.settingsSection + u'/active',
|
||||||
QtCore.QVariant(False)).toBool()
|
QtCore.QVariant(False)).toBool()
|
||||||
@ -133,8 +138,6 @@ class SongUsagePlugin(Plugin):
|
|||||||
translate('SongUsagePlugin', 'Song Usage'))
|
translate('SongUsagePlugin', 'Song Usage'))
|
||||||
action_list.add_action(self.songUsageReport,
|
action_list.add_action(self.songUsageReport,
|
||||||
translate('SongUsagePlugin', 'Song Usage'))
|
translate('SongUsagePlugin', 'Song Usage'))
|
||||||
if self.manager is None:
|
|
||||||
self.manager = Manager(u'songusage', init_schema)
|
|
||||||
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
|
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
|
||||||
self.formparent)
|
self.formparent)
|
||||||
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
|
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
|
||||||
@ -193,10 +196,21 @@ class SongUsagePlugin(Plugin):
|
|||||||
self.songUsageStatus.blockSignals(False)
|
self.songUsageStatus.blockSignals(False)
|
||||||
|
|
||||||
|
|
||||||
def onReceiveSongUsage(self, item):
|
def displaySongUsage(self, item):
|
||||||
"""
|
"""
|
||||||
Song Usage for live song from SlideController
|
Song Usage for which has been displayed
|
||||||
"""
|
"""
|
||||||
|
self._add_song_usage(unicode(translate('SongUsagePlugin',
|
||||||
|
'display')), item)
|
||||||
|
|
||||||
|
def printSongUsage(self, item):
|
||||||
|
"""
|
||||||
|
Song Usage for which has been printed
|
||||||
|
"""
|
||||||
|
self._add_song_usage(unicode(translate('SongUsagePlugin',
|
||||||
|
'printed')), item)
|
||||||
|
|
||||||
|
def _add_song_usage(self, source, item):
|
||||||
audit = item[0].audit
|
audit = item[0].audit
|
||||||
if self.songUsageActive and audit:
|
if self.songUsageActive and audit:
|
||||||
song_usage_item = SongUsageItem()
|
song_usage_item = SongUsageItem()
|
||||||
@ -206,6 +220,8 @@ class SongUsagePlugin(Plugin):
|
|||||||
song_usage_item.copyright = audit[2]
|
song_usage_item.copyright = audit[2]
|
||||||
song_usage_item.ccl_number = audit[3]
|
song_usage_item.ccl_number = audit[3]
|
||||||
song_usage_item.authors = u' '.join(audit[1])
|
song_usage_item.authors = u' '.join(audit[1])
|
||||||
|
song_usage_item.plugin_name = item[0].name
|
||||||
|
song_usage_item.source = source
|
||||||
self.manager.save_object(song_usage_item)
|
self.manager.save_object(song_usage_item)
|
||||||
|
|
||||||
def onSongUsageDelete(self):
|
def onSongUsageDelete(self):
|
||||||
|
@ -11,7 +11,7 @@ Package: openlp
|
|||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4,
|
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4,
|
||||||
python-qt4-phonon, python-sqlalchemy, python-chardet, python-beautifulsoup,
|
python-qt4-phonon, python-sqlalchemy, python-chardet, python-beautifulsoup,
|
||||||
python-lxml, python-sqlite, python-enchant
|
python-lxml, python-sqlite, python-enchant, python-mako, python-migrate
|
||||||
Conflicts: python-openlp
|
Conflicts: python-openlp
|
||||||
Description: Church lyrics projection application
|
Description: Church lyrics projection application
|
||||||
OpenLP is free church presentation software, or lyrics projection software,
|
OpenLP is free church presentation software, or lyrics projection software,
|
||||||
|
1986
resources/i18n/af.ts
1986
resources/i18n/af.ts
File diff suppressed because it is too large
Load Diff
3126
resources/i18n/cs.ts
3126
resources/i18n/cs.ts
File diff suppressed because it is too large
Load Diff
1765
resources/i18n/de.ts
1765
resources/i18n/de.ts
File diff suppressed because it is too large
Load Diff
1797
resources/i18n/en.ts
1797
resources/i18n/en.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2138
resources/i18n/es.ts
2138
resources/i18n/es.ts
File diff suppressed because it is too large
Load Diff
2142
resources/i18n/et.ts
2142
resources/i18n/et.ts
File diff suppressed because it is too large
Load Diff
1994
resources/i18n/fr.ts
1994
resources/i18n/fr.ts
File diff suppressed because it is too large
Load Diff
2530
resources/i18n/hu.ts
2530
resources/i18n/hu.ts
File diff suppressed because it is too large
Load Diff
2020
resources/i18n/id.ts
2020
resources/i18n/id.ts
File diff suppressed because it is too large
Load Diff
2421
resources/i18n/ja.ts
2421
resources/i18n/ja.ts
File diff suppressed because it is too large
Load Diff
1814
resources/i18n/ko.ts
1814
resources/i18n/ko.ts
File diff suppressed because it is too large
Load Diff
1797
resources/i18n/nb.ts
1797
resources/i18n/nb.ts
File diff suppressed because it is too large
Load Diff
1988
resources/i18n/nl.ts
1988
resources/i18n/nl.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2294
resources/i18n/ru.ts
2294
resources/i18n/ru.ts
File diff suppressed because it is too large
Load Diff
1809
resources/i18n/sv.ts
1809
resources/i18n/sv.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -46,14 +46,14 @@ VERS = {
|
|||||||
'sqlalchemy': '0.5',
|
'sqlalchemy': '0.5',
|
||||||
# pyenchant 1.6 required on Windows
|
# pyenchant 1.6 required on Windows
|
||||||
'enchant': '1.6' if is_win else '1.3'
|
'enchant': '1.6' if is_win else '1.3'
|
||||||
}
|
}
|
||||||
|
|
||||||
# pywin32
|
# pywin32
|
||||||
WIN32_MODULES = [
|
WIN32_MODULES = [
|
||||||
'win32com',
|
'win32com',
|
||||||
'win32ui',
|
'win32ui',
|
||||||
'pywintypes',
|
'pywintypes',
|
||||||
]
|
]
|
||||||
|
|
||||||
MODULES = [
|
MODULES = [
|
||||||
'PyQt4',
|
'PyQt4',
|
||||||
@ -72,7 +72,8 @@ MODULES = [
|
|||||||
'enchant',
|
'enchant',
|
||||||
'BeautifulSoup',
|
'BeautifulSoup',
|
||||||
'mako',
|
'mako',
|
||||||
]
|
'migrate',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
OPTIONAL_MODULES = [
|
OPTIONAL_MODULES = [
|
||||||
|
@ -186,25 +186,6 @@ def update_export_at_pootle(source_filename):
|
|||||||
page = urllib.urlopen(REVIEW_URL)
|
page = urllib.urlopen(REVIEW_URL)
|
||||||
page.close()
|
page.close()
|
||||||
|
|
||||||
|
|
||||||
def download_file(source_filename, dest_filename):
|
|
||||||
"""
|
|
||||||
Download a file and save it to disk.
|
|
||||||
|
|
||||||
``source_filename``
|
|
||||||
The file to download.
|
|
||||||
|
|
||||||
``dest_filename``
|
|
||||||
The new local file name.
|
|
||||||
"""
|
|
||||||
print_verbose(u'Downloading from: %s' % (SERVER_URL + source_filename))
|
|
||||||
page = urllib.urlopen(SERVER_URL + source_filename)
|
|
||||||
content = page.read().decode('utf8')
|
|
||||||
page.close()
|
|
||||||
file = open(dest_filename, u'w')
|
|
||||||
file.write(content.encode('utf8'))
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def download_translations():
|
def download_translations():
|
||||||
"""
|
"""
|
||||||
This method downloads the translation files from the Pootle server.
|
This method downloads the translation files from the Pootle server.
|
||||||
@ -219,7 +200,7 @@ def download_translations():
|
|||||||
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n',
|
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n',
|
||||||
language_file)
|
language_file)
|
||||||
print_verbose(u'Get Translation File: %s' % filename)
|
print_verbose(u'Get Translation File: %s' % filename)
|
||||||
download_file(language_file, filename)
|
urllib.urlretrieve(SERVER_URL + language_file, filename)
|
||||||
print_quiet(u' Done.')
|
print_quiet(u' Done.')
|
||||||
|
|
||||||
def prepare_project():
|
def prepare_project():
|
||||||
@ -304,7 +285,7 @@ def create_translation(language):
|
|||||||
if not language.endswith(u'.ts'):
|
if not language.endswith(u'.ts'):
|
||||||
language += u'.ts'
|
language += u'.ts'
|
||||||
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language)
|
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language)
|
||||||
download_file(u'en.ts', filename)
|
urllib.urlretrieve(SERVER_URL + u'en.ts', filename)
|
||||||
print_quiet(u' ** Please Note **')
|
print_quiet(u' ** Please Note **')
|
||||||
print_quiet(u' In order to get this file into OpenLP and onto the '
|
print_quiet(u' In order to get this file into OpenLP and onto the '
|
||||||
u'Pootle translation server you will need to subscribe to the '
|
u'Pootle translation server you will need to subscribe to the '
|
||||||
|
Loading…
Reference in New Issue
Block a user