Merge trunk

This commit is contained in:
Jonathan Springer 2013-12-09 07:19:36 -05:00
commit 79a2a5b1db
9 changed files with 225 additions and 30 deletions

View File

@ -33,7 +33,6 @@ import os
import zipfile
import shutil
import logging
import re
from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui
@ -59,7 +58,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
"""
super(ThemeManager, self).__init__(parent)
Registry().register('theme_manager', self)
Registry().register_function('bootstrap_initialise', self.load_first_time_themes)
Registry().register_function('bootstrap_initialise', self.initialise)
Registry().register_function('bootstrap_post_set_up', self._push_themes)
self.settings_section = 'themes'
self.theme_form = ThemeForm(self)
@ -135,15 +134,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
Registry().register_function('theme_update_global', self.change_global_from_tab)
# Variables
self.theme_list = []
self.path = AppLocation.get_section_data_path(self.settings_section)
check_directory_exists(self.path)
self.thumb_path = os.path.join(self.path, 'thumbnails')
check_directory_exists(self.thumb_path)
self.theme_form.path = self.path
self.old_background_image = None
self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
# Last little bits of setting up
self.global_theme = Settings().value(self.settings_section + '/global theme')
def check_list_state(self, item):
"""
@ -392,6 +383,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
"""
Imports any themes on start up and makes sure there is at least one theme
"""
log.debug('load_first_time_themes called')
self.application.set_busy_cursor()
files = AppLocation.get_files(self.settings_section, '.otz')
for theme_file in files:
@ -410,8 +402,8 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
def load_themes(self):
"""
Loads the theme lists and triggers updates across the whole system
using direct calls or core functions and events for the plugins.
Loads the theme lists and triggers updates across the whole system using direct calls or core functions and
events for the plugins.
The plugins will call back in to get the real list if they want it.
"""
log.debug('Load themes from dir')
@ -636,18 +628,18 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
self.main_window.finished_progress_bar()
self.load_themes()
def generate_image(self, theme_data, forcePage=False):
def generate_image(self, theme_data, force_page=False):
"""
Call the renderer to build a Sample Image
``theme_data``
The theme to generated a preview for.
``forcePage``
``force_page``
Flag to tell message lines per page need to be generated.
"""
log.debug('generate_image \n%s ', theme_data)
return self.renderer.generate_preview(theme_data, forcePage)
return self.renderer.generate_preview(theme_data, force_page)
def get_preview_image(self, theme):
"""
@ -672,7 +664,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
theme.extend_image_filename(path)
return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text, testPlugin=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.
@ -694,7 +686,7 @@ class ThemeManager(QtGui.QWidget, ThemeManagerHelper):
message=translate('OpenLP.ThemeManager', 'You are unable to delete the default theme.'))
return False
# check for use in the system else where.
if testPlugin:
if test_plugin:
for plugin in self.plugin_manager.plugins:
if plugin.uses_theme(theme):
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),

View File

@ -29,10 +29,34 @@
"""
The Theme Controller helps manages adding, deleteing and modifying of themes.
"""
import logging
import os
from openlp.core.common import AppLocation, Settings, check_directory_exists
log = logging.getLogger(__name__)
class ThemeManagerHelper(object):
"""
Manages the non ui theme functions.
"""
pass
def initialise(self):
"""
Setup the manager
"""
log.debug('initialise called')
self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path()
self.load_first_time_themes()
def build_theme_path(self):
"""
Set up the theme path variables
"""
log.debug('build theme path called')
self.path = AppLocation.get_section_data_path(self.settings_section)
check_directory_exists(self.path)
self.thumb_path = os.path.join(self.path, 'thumbnails')
check_directory_exists(self.thumb_path)
self.theme_form.path = self.path

View File

@ -281,7 +281,7 @@ class Controller(object):
class MessageListener(object):
"""
This is the Presentation listener who acts on events from the slide controller and passes the messages on the the
This is the Presentation listener who acts on events from the slide controller and passes the messages on the
correct presentation handlers
"""
log.info('Message Listener loaded')
@ -316,7 +316,7 @@ class MessageListener(object):
hide_mode = message[2]
file = item.get_frame_path()
self.handler = item.processor
if self.handler == self.media_item.Automatic:
if self.handler == self.media_item.automatic:
self.handler = self.media_item.findControllerByType(file)
if not self.handler:
return

View File

@ -292,8 +292,8 @@ class PresentationDocument(object):
class PresentationController(object):
"""
This class is used to control interactions with presentation applications by creating a runtime environment. This is
a base class for presentation controllers to inherit from.
This class is used to control interactions with presentation applications by creating a runtime environment.
This is a base class for presentation controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends with ``controller.py``, i.e.
``foobarcontroller.py``. Make sure it inherits
@ -341,8 +341,7 @@ class PresentationController(object):
"""
log.info('PresentationController loaded')
def __init__(self, plugin=None, name='PresentationController',
document_class=PresentationDocument):
def __init__(self, plugin=None, name='PresentationController', document_class=PresentationDocument):
"""
This is the constructor for the presentationcontroller object. This provides an easy way for descendent plugins
to populate common data. This method *must* be overridden, like so::

View File

@ -1 +1,28 @@
__author__ = 'tim'
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################

View File

@ -59,7 +59,6 @@ class TestAppLocation(TestCase):
# WHEN: we call AppLocation.get_data_path()
data_path = AppLocation.get_data_path()
print(data_path)
# THEN: check that all the correct methods were called, and the result is correct
mocked_settings.contains.assert_called_with('advanced/data path')

View File

@ -62,9 +62,11 @@ class TestTheme(TestCase):
# THEN: We should get some default behaviours
self.assertTrue(default_theme.background_border_color == '#000000', 'The theme should have a black border')
self.assertTrue(default_theme.background_type == 'solid', 'There theme should have a solid backgrounds')
self.assertTrue(default_theme.background_type == 'solid', 'The theme should have a solid backgrounds')
self.assertTrue(default_theme.display_vertical_align == 0,
'There theme should have display_vertical_align of 0')
'The theme should have a display_vertical_align of 0')
self.assertTrue(default_theme.font_footer_name == "Arial",
'There theme should has font_footer_name of Arial')
self.assertTrue(default_theme.font_main_bold is False, 'There theme should has font_main_bold of false')
'The theme should have a font_footer_name of Arial')
self.assertTrue(default_theme.font_main_bold is False, 'The theme should have a font_main_bold of false')
self.assertTrue(len(default_theme.__dict__) == 47, 'The theme should have 47 variables')

View File

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
This module contains tests for the Presentation Controller.
"""
from unittest import TestCase
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController
from tests.functional import MagicMock
class TestPresentationController(TestCase):
"""
Test the PresentationController.
"""
def constructor_test(self):
"""
Test the Constructor
"""
# GIVEN: No presentation controller
controller = None
# WHEN: The presentation controller object is created
controller = PresentationController(plugin=MagicMock())
# THEN: The name of the presentation controller should be correct
self.assertEqual('PresentationController', controller.name,
'The name of the presentation controller should be correct')

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Interface tests to test the thememanagerhelper class and related methods.
"""
import os
from unittest import TestCase
from tempfile import mkstemp
from openlp.core.common import Settings
from openlp.core.ui import ThemeManagerHelper
from tests.functional import patch, MagicMock
class TestThemeManagerHelper(TestCase):
"""
Test the functions in the ThemeManagerHelp[er module
"""
def setUp(self):
"""
Create the UI
"""
fd, self.ini_file = mkstemp('.ini')
Settings().set_filename(self.ini_file)
self.helper = ThemeManagerHelper()
self.helper.settings_section = "themes"
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
os.unlink(self.ini_file)
os.unlink(Settings().fileName())
def test_initialise(self):
"""
Test the thememanagerhelper initialise - basic test
"""
# GIVEN: A new a call to initialise
Settings().setValue('themes/global theme', 'my_theme')
self.helper.build_theme_path = MagicMock()
self.helper.load_first_time_themes = MagicMock()
# WHEN: the initialistion is run
self.helper.initialise()
# THEN:
self.assertEqual(1, self.helper.build_theme_path.call_count,
'The function build_theme_path should have been called')
self.assertEqual(1, self.helper.load_first_time_themes.call_count,
'The function load_first_time_themes should have been called only once')
self.assertEqual(self.helper.global_theme, 'my_theme',
'The global theme should have been set to my_theme')
def test_build_theme_path(self):
"""
Test the thememanagerhelper build_theme_path - basic test
"""
# GIVEN: A new a call to initialise
with patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists:
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
mocked_check_directory_exists.return_value = True
Settings().setValue('themes/global theme', 'my_theme')
self.helper.theme_form = MagicMock()
#self.helper.load_first_time_themes = MagicMock()
# WHEN: the build_theme_path is run
self.helper.build_theme_path()
# THEN:
self.assertEqual(self.helper.path, self.helper.theme_form.path,
'The theme path and the main path should be the same value')