theme clean up

This commit is contained in:
Tim Bentley 2017-05-13 08:47:22 +01:00
parent 4183f186ce
commit 48a87780d4
4 changed files with 330 additions and 282 deletions

View File

@ -438,3 +438,13 @@ def get_file_encoding(filename):
return detector.result return detector.result
except OSError: except OSError:
log.exception('Error detecting file encoding') log.exception('Error detecting file encoding')
def json_default(o):
"""
Function to help save objects as JSON
:param o: object
:return: the object dictionary
"""
return o.__dict__

View File

@ -150,7 +150,7 @@ INTEGER_LIST = ['size', 'line_adjustment', 'x', 'height', 'y', 'width', 'shadow_
'horizontal_align', 'vertical_align', 'wrap_style'] 'horizontal_align', 'vertical_align', 'wrap_style']
class ThemeXML(object): class Theme(object):
""" """
A class to encapsulate the Theme XML. A class to encapsulate the Theme XML.
""" """
@ -195,183 +195,183 @@ class ThemeXML(object):
self.background_filename = self.background_filename.strip() self.background_filename = self.background_filename.strip()
self.background_filename = os.path.join(path, self.theme_name, self.background_filename) self.background_filename = os.path.join(path, self.theme_name, self.background_filename)
def _new_document(self, name): # def _new_document(self, name):
""" # """
Create a new theme XML document. # Create a new theme XML document.
""" # """
self.theme_xml = Document() # self.theme_xml = Document()
self.theme = self.theme_xml.createElement('theme') # self.theme = self.theme_xml.createElement('theme')
self.theme_xml.appendChild(self.theme) # self.theme_xml.appendChild(self.theme)
self.theme.setAttribute('version', '2.0') # self.theme.setAttribute('version', '2.0')
self.name = self.theme_xml.createElement('name') # self.name = self.theme_xml.createElement('name')
text_node = self.theme_xml.createTextNode(name) # text_node = self.theme_xml.createTextNode(name)
self.name.appendChild(text_node) # self.name.appendChild(text_node)
self.theme.appendChild(self.name) # self.theme.appendChild(self.name)
def add_background_transparent(self): # def add_background_transparent(self):
""" # """
Add a transparent background. # Add a transparent background.
""" # """
background = self.theme_xml.createElement('background') # background = self.theme_xml.createElement('background')
background.setAttribute('type', 'transparent') # background.setAttribute('type', 'transparent')
self.theme.appendChild(background) # self.theme.appendChild(background)
def add_background_solid(self, bkcolor): # def add_background_solid(self, bkcolor):
""" # """
Add a Solid background. # Add a Solid background.
#
# :param bkcolor: The color of the background.
# """
# background = self.theme_xml.createElement('background')
# background.setAttribute('type', 'solid')
# self.theme.appendChild(background)
# self.child_element(background, 'color', str(bkcolor))
:param bkcolor: The color of the background. # def add_background_gradient(self, startcolor, endcolor, direction):
""" # """
background = self.theme_xml.createElement('background') # Add a gradient background.
background.setAttribute('type', 'solid') #
self.theme.appendChild(background) # :param startcolor: The gradient's starting colour.
self.child_element(background, 'color', str(bkcolor)) # :param endcolor: The gradient's ending colour.
# :param direction: The direction of the gradient.
# """
# background = self.theme_xml.createElement('background')
# background.setAttribute('type', 'gradient')
# self.theme.appendChild(background)
# # Create startColor element
# self.child_element(background, 'startColor', str(startcolor))
# # Create endColor element
# self.child_element(background, 'endColor', str(endcolor))
# # Create direction element
# self.child_element(background, 'direction', str(direction))
def add_background_gradient(self, startcolor, endcolor, direction): # def add_background_image(self, filename, border_color):
""" # """
Add a gradient background. # Add a image background.
#
# :param filename: The file name of the image.
# :param border_color:
# """
# background = self.theme_xml.createElement('background')
# background.setAttribute('type', 'image')
# self.theme.appendChild(background)
# # Create Filename element
# self.child_element(background, 'filename', filename)
# # Create endColor element
# self.child_element(background, 'borderColor', str(border_color))
#
# def add_background_video(self, filename, border_color):
# """
# Add a video background.
#
# :param filename: The file name of the video.
# :param border_color:
# """
# background = self.theme_xml.createElement('background')
# background.setAttribute('type', 'video')
# self.theme.appendChild(background)
# # Create Filename element
# self.child_element(background, 'filename', filename)
# # Create endColor element
# self.child_element(background, 'borderColor', str(border_color))
:param startcolor: The gradient's starting colour. # def add_font(self, name, color, size, override, fonttype='main', bold='False', italics='False',
:param endcolor: The gradient's ending colour. # line_adjustment=0, xpos=0, ypos=0, width=0, height=0, outline='False', outline_color='#ffffff',
:param direction: The direction of the gradient. # outline_pixel=2, shadow='False', shadow_color='#ffffff', shadow_pixel=5):
""" # """
background = self.theme_xml.createElement('background') # Add a Font.
background.setAttribute('type', 'gradient') #
self.theme.appendChild(background) # :param name: The name of the font.
# Create startColor element # :param color: The colour of the font.
self.child_element(background, 'startColor', str(startcolor)) # :param size: The size of the font.
# Create endColor element # :param override: Whether or not to override the default positioning of the theme.
self.child_element(background, 'endColor', str(endcolor)) # :param fonttype: The type of font, ``main`` or ``footer``. Defaults to ``main``.
# Create direction element # :param bold:
self.child_element(background, 'direction', str(direction)) # :param italics: The weight of then font Defaults to 50 Normal
# :param line_adjustment: Does the font render to italics Defaults to 0 Normal
def add_background_image(self, filename, border_color): # :param xpos: The X position of the text block.
""" # :param ypos: The Y position of the text block.
Add a image background. # :param width: The width of the text block.
# :param height: The height of the text block.
:param filename: The file name of the image. # :param outline: Whether or not to show an outline.
:param border_color: # :param outline_color: The colour of the outline.
""" # :param outline_pixel: How big the Shadow is
background = self.theme_xml.createElement('background') # :param shadow: Whether or not to show a shadow.
background.setAttribute('type', 'image') # :param shadow_color: The colour of the shadow.
self.theme.appendChild(background) # :param shadow_pixel: How big the Shadow is
# Create Filename element # """
self.child_element(background, 'filename', filename) # background = self.theme_xml.createElement('font')
# Create endColor element # background.setAttribute('type', fonttype)
self.child_element(background, 'borderColor', str(border_color)) # self.theme.appendChild(background)
# # Create Font name element
def add_background_video(self, filename, border_color): # self.child_element(background, 'name', name)
""" # # Create Font color element
Add a video background. # self.child_element(background, 'color', str(color))
# # Create Proportion name element
:param filename: The file name of the video. # self.child_element(background, 'size', str(size))
:param border_color: # # Create weight name element
""" # self.child_element(background, 'bold', str(bold))
background = self.theme_xml.createElement('background') # # Create italics name element
background.setAttribute('type', 'video') # self.child_element(background, 'italics', str(italics))
self.theme.appendChild(background) # # Create indentation name element
# Create Filename element # self.child_element(background, 'line_adjustment', str(line_adjustment))
self.child_element(background, 'filename', filename) # # Create Location element
# Create endColor element # element = self.theme_xml.createElement('location')
self.child_element(background, 'borderColor', str(border_color)) # element.setAttribute('override', str(override))
# element.setAttribute('x', str(xpos))
def add_font(self, name, color, size, override, fonttype='main', bold='False', italics='False', # element.setAttribute('y', str(ypos))
line_adjustment=0, xpos=0, ypos=0, width=0, height=0, outline='False', outline_color='#ffffff', # element.setAttribute('width', str(width))
outline_pixel=2, shadow='False', shadow_color='#ffffff', shadow_pixel=5): # element.setAttribute('height', str(height))
""" # background.appendChild(element)
Add a Font. # # Shadow
# element = self.theme_xml.createElement('shadow')
:param name: The name of the font. # element.setAttribute('shadowColor', str(shadow_color))
:param color: The colour of the font. # element.setAttribute('shadowSize', str(shadow_pixel))
:param size: The size of the font. # value = self.theme_xml.createTextNode(str(shadow))
:param override: Whether or not to override the default positioning of the theme. # element.appendChild(value)
:param fonttype: The type of font, ``main`` or ``footer``. Defaults to ``main``. # background.appendChild(element)
:param bold: # # Outline
:param italics: The weight of then font Defaults to 50 Normal # element = self.theme_xml.createElement('outline')
:param line_adjustment: Does the font render to italics Defaults to 0 Normal # element.setAttribute('outlineColor', str(outline_color))
:param xpos: The X position of the text block. # element.setAttribute('outlineSize', str(outline_pixel))
:param ypos: The Y position of the text block. # value = self.theme_xml.createTextNode(str(outline))
:param width: The width of the text block. # element.appendChild(value)
:param height: The height of the text block. # background.appendChild(element)
:param outline: Whether or not to show an outline. #
:param outline_color: The colour of the outline. # def add_display(self, horizontal, vertical, transition):
:param outline_pixel: How big the Shadow is # """
:param shadow: Whether or not to show a shadow. # Add a Display options.
:param shadow_color: The colour of the shadow. #
:param shadow_pixel: How big the Shadow is # :param horizontal: The horizontal alignment of the text.
""" # :param vertical: The vertical alignment of the text.
background = self.theme_xml.createElement('font') # :param transition: Whether the slide transition is active.
background.setAttribute('type', fonttype) # """
self.theme.appendChild(background) # background = self.theme_xml.createElement('display')
# Create Font name element # self.theme.appendChild(background)
self.child_element(background, 'name', name) # # Horizontal alignment
# Create Font color element # element = self.theme_xml.createElement('horizontalAlign')
self.child_element(background, 'color', str(color)) # value = self.theme_xml.createTextNode(str(horizontal))
# Create Proportion name element # element.appendChild(value)
self.child_element(background, 'size', str(size)) # background.appendChild(element)
# Create weight name element # # Vertical alignment
self.child_element(background, 'bold', str(bold)) # element = self.theme_xml.createElement('verticalAlign')
# Create italics name element # value = self.theme_xml.createTextNode(str(vertical))
self.child_element(background, 'italics', str(italics)) # element.appendChild(value)
# Create indentation name element # background.appendChild(element)
self.child_element(background, 'line_adjustment', str(line_adjustment)) # # Slide Transition
# Create Location element # element = self.theme_xml.createElement('slideTransition')
element = self.theme_xml.createElement('location') # value = self.theme_xml.createTextNode(str(transition))
element.setAttribute('override', str(override)) # element.appendChild(value)
element.setAttribute('x', str(xpos)) # background.appendChild(element)
element.setAttribute('y', str(ypos)) #
element.setAttribute('width', str(width)) # def child_element(self, element, tag, value):
element.setAttribute('height', str(height)) # """
background.appendChild(element) # Generic child element creator.
# Shadow # """
element = self.theme_xml.createElement('shadow') # child = self.theme_xml.createElement(tag)
element.setAttribute('shadowColor', str(shadow_color)) # child.appendChild(self.theme_xml.createTextNode(value))
element.setAttribute('shadowSize', str(shadow_pixel)) # element.appendChild(child)
value = self.theme_xml.createTextNode(str(shadow)) # return child
element.appendChild(value)
background.appendChild(element)
# Outline
element = self.theme_xml.createElement('outline')
element.setAttribute('outlineColor', str(outline_color))
element.setAttribute('outlineSize', str(outline_pixel))
value = self.theme_xml.createTextNode(str(outline))
element.appendChild(value)
background.appendChild(element)
def add_display(self, horizontal, vertical, transition):
"""
Add a Display options.
:param horizontal: The horizontal alignment of the text.
:param vertical: The vertical alignment of the text.
:param transition: Whether the slide transition is active.
"""
background = self.theme_xml.createElement('display')
self.theme.appendChild(background)
# Horizontal alignment
element = self.theme_xml.createElement('horizontalAlign')
value = self.theme_xml.createTextNode(str(horizontal))
element.appendChild(value)
background.appendChild(element)
# Vertical alignment
element = self.theme_xml.createElement('verticalAlign')
value = self.theme_xml.createTextNode(str(vertical))
element.appendChild(value)
background.appendChild(element)
# Slide Transition
element = self.theme_xml.createElement('slideTransition')
value = self.theme_xml.createTextNode(str(transition))
element.appendChild(value)
background.appendChild(element)
def child_element(self, element, tag, value):
"""
Generic child element creator.
"""
child = self.theme_xml.createElement(tag)
child.appendChild(self.theme_xml.createTextNode(value))
element.appendChild(child)
return child
def set_default_header_footer(self): def set_default_header_footer(self):
""" """
@ -386,25 +386,34 @@ class ThemeXML(object):
self.font_footer_y = current_screen['size'].height() * 9 / 10 self.font_footer_y = current_screen['size'].height() * 9 / 10
self.font_footer_height = current_screen['size'].height() / 10 self.font_footer_height = current_screen['size'].height() / 10
def dump_xml(self): # def dump_xml(self):
""" # """
Dump the XML to file used for debugging # Dump the XML to file used for debugging
""" # """
return self.theme_xml.toprettyxml(indent=' ') # return self.theme_xml.toprettyxml(indent=' ')
def extract_xml(self): # def extract_xml(self):
""" # """
Print out the XML string. # Print out the XML string.
""" # """
self._build_xml_from_attrs() # self._build_xml_from_attrs()
return self.theme_xml.toxml('utf-8').decode('utf-8') # return self.theme_xml.toxml('utf-8').decode('utf-8')
#
# def extract_formatted_xml(self):
# """
# Pull out the XML string formatted for human consumption
# """
# self._build_xml_from_attrs()
# return self.theme_xml.toprettyxml(indent=' ', newl='\n', encoding='utf-8')
def extract_formatted_xml(self): def load_theme(self, theme):
""" """
Pull out the XML string formatted for human consumption Pull out the XML string formatted for human consumption
:param theme: the theme string
""" """
self._build_xml_from_attrs() jsn = json.loads(theme)
return self.theme_xml.toprettyxml(indent=' ', newl='\n', encoding='utf-8') self.expand_json(jsn)
def parse(self, xml): def parse(self, xml):
""" """
@ -461,7 +470,8 @@ class ThemeXML(object):
if element.tag == 'name': if element.tag == 'name':
self._create_attr('theme', element.tag, element.text) self._create_attr('theme', element.tag, element.text)
def _translate_tags(self, master, element, value): @staticmethod
def _translate_tags(master, element, value):
""" """
Clean up XML removing and redefining tags Clean up XML removing and redefining tags
""" """
@ -514,71 +524,70 @@ class ThemeXML(object):
theme_strings = [] theme_strings = []
for key in dir(self): for key in dir(self):
if key[0:1] != '_': if key[0:1] != '_':
# TODO: Due to bound methods returned, I don't know how to write a proper test
theme_strings.append('{key:>30}: {value}'.format(key=key, value=getattr(self, key))) theme_strings.append('{key:>30}: {value}'.format(key=key, value=getattr(self, key)))
return '\n'.join(theme_strings) return '\n'.join(theme_strings)
def _build_xml_from_attrs(self): # def _build_xml_from_attrs(self):
""" # """
Build the XML from the varables in the object # Build the XML from the varables in the object
""" # """
self._new_document(self.theme_name) # self._new_document(self.theme_name)
if self.background_type == BackgroundType.to_string(BackgroundType.Solid): # if self.background_type == BackgroundType.to_string(BackgroundType.Solid):
self.add_background_solid(self.background_color) # self.add_background_solid(self.background_color)
elif self.background_type == BackgroundType.to_string(BackgroundType.Gradient): # elif self.background_type == BackgroundType.to_string(BackgroundType.Gradient):
self.add_background_gradient( # self.add_background_gradient(
self.background_start_color, # self.background_start_color,
self.background_end_color, # self.background_end_color,
self.background_direction # self.background_direction
) # )
elif self.background_type == BackgroundType.to_string(BackgroundType.Image): # elif self.background_type == BackgroundType.to_string(BackgroundType.Image):
filename = os.path.split(self.background_filename)[1] # filename = os.path.split(self.background_filename)[1]
self.add_background_image(filename, self.background_border_color) # self.add_background_image(filename, self.background_border_color)
elif self.background_type == BackgroundType.to_string(BackgroundType.Video): # elif self.background_type == BackgroundType.to_string(BackgroundType.Video):
filename = os.path.split(self.background_filename)[1] # filename = os.path.split(self.background_filename)[1]
self.add_background_video(filename, self.background_border_color) # self.add_background_video(filename, self.background_border_color)
elif self.background_type == BackgroundType.to_string(BackgroundType.Transparent): # elif self.background_type == BackgroundType.to_string(BackgroundType.Transparent):
self.add_background_transparent() # self.add_background_transparent()
self.add_font( # self.add_font(
self.font_main_name, # self.font_main_name,
self.font_main_color, # self.font_main_color,
self.font_main_size, # self.font_main_size,
self.font_main_override, 'main', # self.font_main_override, 'main',
self.font_main_bold, # self.font_main_bold,
self.font_main_italics, # self.font_main_italics,
self.font_main_line_adjustment, # self.font_main_line_adjustment,
self.font_main_x, # self.font_main_x,
self.font_main_y, # self.font_main_y,
self.font_main_width, # self.font_main_width,
self.font_main_height, # self.font_main_height,
self.font_main_outline, # self.font_main_outline,
self.font_main_outline_color, # self.font_main_outline_color,
self.font_main_outline_size, # self.font_main_outline_size,
self.font_main_shadow, # self.font_main_shadow,
self.font_main_shadow_color, # self.font_main_shadow_color,
self.font_main_shadow_size # self.font_main_shadow_size
) # )
self.add_font( # self.add_font(
self.font_footer_name, # self.font_footer_name,
self.font_footer_color, # self.font_footer_color,
self.font_footer_size, # self.font_footer_size,
self.font_footer_override, 'footer', # self.font_footer_override, 'footer',
self.font_footer_bold, # self.font_footer_bold,
self.font_footer_italics, # self.font_footer_italics,
0, # line adjustment # 0, # line adjustment
self.font_footer_x, # self.font_footer_x,
self.font_footer_y, # self.font_footer_y,
self.font_footer_width, # self.font_footer_width,
self.font_footer_height, # self.font_footer_height,
self.font_footer_outline, # self.font_footer_outline,
self.font_footer_outline_color, # self.font_footer_outline_color,
self.font_footer_outline_size, # self.font_footer_outline_size,
self.font_footer_shadow, # self.font_footer_shadow,
self.font_footer_shadow_color, # self.font_footer_shadow_color,
self.font_footer_shadow_size # self.font_footer_shadow_size
) # )
self.add_display( # self.add_display(
self.display_horizontal_align, # self.display_horizontal_align,
self.display_vertical_align, # self.display_vertical_align,
self.display_slide_transition # self.display_slide_transition
) # )

View File

@ -22,6 +22,7 @@
""" """
The Theme Manager manages adding, deleteing and modifying of themes. The Theme Manager manages adding, deleteing and modifying of themes.
""" """
import json
import os import os
import zipfile import zipfile
import shutil import shutil
@ -30,10 +31,10 @@ from xml.etree.ElementTree import ElementTree, XML
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, OpenLPMixin, RegistryMixin, \ from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, OpenLPMixin, RegistryMixin, \
check_directory_exists, UiStrings, translate, is_win, get_filesystem_encoding, delete_file check_directory_exists, UiStrings, translate, is_win, get_filesystem_encoding, delete_file, json_default
from openlp.core.lib import FileDialog, ImageSource, ValidationError, get_text_file_string, build_icon, \ from openlp.core.lib import FileDialog, ImageSource, ValidationError, get_text_file_string, build_icon, \
check_item_selected, create_thumb, validate_thumb check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.theme import ThemeXML, BackgroundType from openlp.core.lib.theme import Theme, BackgroundType
from openlp.core.lib.ui import critical_error_message_box, create_widget_action from openlp.core.lib.ui import critical_error_message_box, create_widget_action
from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.ui.lib import OpenLPToolbar from openlp.core.ui.lib import OpenLPToolbar
@ -245,7 +246,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
their customisations. their customisations.
:param field: :param field:
""" """
theme = ThemeXML() theme = Theme()
theme.set_default_header_footer() theme.set_default_header_footer()
self.theme_form.theme = theme self.theme_form.theme = theme
self.theme_form.exec() self.theme_form.exec()
@ -452,7 +453,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
files = AppLocation.get_files(self.settings_section, '.png') files = AppLocation.get_files(self.settings_section, '.png')
# No themes have been found so create one # No themes have been found so create one
if not files: if not files:
theme = ThemeXML() theme = Theme()
theme.theme_name = UiStrings().Default theme.theme_name = UiStrings().Default
self._write_theme(theme, None, None) self._write_theme(theme, None, None)
Settings().setValue(self.settings_section + '/global theme', theme.theme_name) Settings().setValue(self.settings_section + '/global theme', theme.theme_name)
@ -515,7 +516,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
xml = get_text_file_string(xml_file) xml = get_text_file_string(xml_file)
if not xml: if not xml:
self.log_debug('No theme data - using default theme') self.log_debug('No theme data - using default theme')
return ThemeXML() return Theme()
else: else:
return self._create_theme_from_xml(xml, self.path) return self._create_theme_from_xml(xml, self.path)
@ -646,16 +647,16 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
:param image_to: Where the Theme Image is to be saved to :param image_to: Where the Theme Image is to be saved to
""" """
name = theme.theme_name name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml() theme_pretty = json.dumps(theme, default=json_default)
theme_dir = os.path.join(self.path, name) theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir) check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + '.xml') theme_file = os.path.join(theme_dir, name + '.json')
if self.old_background_image and image_to != self.old_background_image: if self.old_background_image and image_to != self.old_background_image:
delete_file(self.old_background_image) delete_file(self.old_background_image)
out_file = None out_file = None
try: try:
out_file = open(theme_file, 'w', encoding='utf-8') out_file = open(theme_file, 'w', encoding='utf-8')
out_file.write(theme_pretty_xml.decode('utf-8')) out_file.write(theme_pretty)
except IOError: except IOError:
self.log_exception('Saving theme to file failed') self.log_exception('Saving theme to file failed')
finally: finally:
@ -717,7 +718,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
""" """
return os.path.join(self.path, theme + '.png') return os.path.join(self.path, theme + '.png')
def _create_theme_from_xml(self, theme_xml, image_path): @staticmethod
def _create_theme_from_xml(theme_xml, image_path):
""" """
Return a theme object using information parsed from XML Return a theme object using information parsed from XML
@ -725,11 +727,25 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
:param image_path: Where the theme image is stored :param image_path: Where the theme image is stored
:return: Theme data. :return: Theme data.
""" """
theme = ThemeXML() theme = Theme()
theme.parse(theme_xml) theme.parse(theme_xml)
theme.extend_image_filename(image_path) theme.extend_image_filename(image_path)
return theme return theme
@staticmethod
def _create_theme_from_json(theme_json, image_path):
"""
Return a theme object using information parsed from JSON
:param theme_json: The Theme data object.
:param image_path: Where the theme image is stored
:return: Theme data.
"""
theme = Theme()
theme.load_theme(theme_json)
theme.extend_image_filename(image_path)
return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text, test_plugin=True, confirm=True): def _validate_theme_action(self, select_text, confirm_title, confirm_text, test_plugin=True, confirm=True):
""" """
Check to see if theme has been selected and the destructive action is allowed. Check to see if theme has been selected and the destructive action is allowed.

View File

@ -22,39 +22,35 @@
""" """
Package to test the openlp.core.lib.theme package. Package to test the openlp.core.lib.theme package.
""" """
import json
from unittest import TestCase from unittest import TestCase
import os import os
from openlp.core.lib.theme import ThemeXML from openlp.core.common import json_default
from openlp.core.lib.theme import Theme
class TestThemeXML(TestCase): class TestTheme(TestCase):
""" """
Test the ThemeXML class Test the ThemeL class
""" """
def test_new_theme(self): def test_new_theme(self):
""" """
Test the ThemeXML constructor Test the Theme constructor
""" """
# GIVEN: The ThemeXML class # GIVEN: The ThemeXML class
# WHEN: A theme object is created # WHEN: A theme object is created
default_theme = ThemeXML() default_theme = Theme()
# THEN: The default values should be correct # THEN: The default values should be correct
self.assertEqual('#000000', default_theme.background_border_color, self.check_theme(default_theme)
'background_border_color should be "#000000"')
self.assertEqual('solid', default_theme.background_type, 'background_type should be "solid"')
self.assertEqual(0, default_theme.display_vertical_align, 'display_vertical_align should be 0')
self.assertEqual('Arial', default_theme.font_footer_name, 'font_footer_name should be "Arial"')
self.assertFalse(default_theme.font_main_bold, 'font_main_bold should be False')
self.assertEqual(47, len(default_theme.__dict__), 'The theme should have 47 attributes')
def test_expand_json(self): def test_expand_json(self):
""" """
Test the expand_json method Test the expand_json method
""" """
# GIVEN: A ThemeXML object and some JSON to "expand" # GIVEN: A ThemeXML object and some JSON to "expand"
theme = ThemeXML() theme = Theme()
theme_json = { theme_json = {
'background': { 'background': {
'border_color': '#000000', 'border_color': '#000000',
@ -77,18 +73,14 @@ class TestThemeXML(TestCase):
theme.expand_json(theme_json) theme.expand_json(theme_json)
# THEN: The attributes should be set on the object # THEN: The attributes should be set on the object
self.assertEqual('#000000', theme.background_border_color, 'background_border_color should be "#000000"') self.check_theme(theme)
self.assertEqual('solid', theme.background_type, 'background_type should be "solid"')
self.assertEqual(0, theme.display_vertical_align, 'display_vertical_align should be 0')
self.assertFalse(theme.font_footer_bold, 'font_footer_bold should be False')
self.assertEqual('Arial', theme.font_main_name, 'font_main_name should be "Arial"')
def test_extend_image_filename(self): def test_extend_image_filename(self):
""" """
Test the extend_image_filename method Test the extend_image_filename method
""" """
# GIVEN: A theme object # GIVEN: A theme object
theme = ThemeXML() theme = Theme()
theme.theme_name = 'MyBeautifulTheme ' theme.theme_name = 'MyBeautifulTheme '
theme.background_filename = ' video.mp4' theme.background_filename = ' video.mp4'
theme.background_type = 'video' theme.background_type = 'video'
@ -101,3 +93,24 @@ class TestThemeXML(TestCase):
expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4') expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4')
self.assertEqual(expected_filename, theme.background_filename) self.assertEqual(expected_filename, theme.background_filename)
self.assertEqual('MyBeautifulTheme', theme.theme_name) self.assertEqual('MyBeautifulTheme', theme.theme_name)
def test_save_retrieve(self):
"""
Load a dummy theme, save it and reload it
"""
# GIVEN: The default Theme class
# WHEN: A theme object is created
default_theme = Theme()
# THEN: The default values should be correct
save_theme_json = json.dumps(default_theme, default=json_default)
lt = Theme()
lt.load_theme(save_theme_json)
self.check_theme(lt)
def check_theme(self, theme):
self.assertEqual('#000000', theme.background_border_color, 'background_border_color should be "#000000"')
self.assertEqual('solid', theme.background_type, 'background_type should be "solid"')
self.assertEqual(0, theme.display_vertical_align, 'display_vertical_align should be 0')
self.assertFalse(theme.font_footer_bold, 'font_footer_bold should be False')
self.assertEqual('Arial', theme.font_main_name, 'font_main_name should be "Arial"')
self.assertEqual(47, len(theme.__dict__), 'The theme should have 47 attributes')