Update the UI on Mac OS to make it look and feel more like a first-class Mac app.

* Removed the icons from the menus (thanks to Jonathan S. for that)
* Use Mac OS X wizards instead of our Windows-style wizards when on OS X

bzr-revno: 2419
This commit is contained in:
Raoul Snyman 2014-09-14 15:07:31 +02:00
commit efe030b020
17 changed files with 181 additions and 91 deletions

View File

@ -36,10 +36,9 @@ if __name__ == '__main__':
"""
Instantiate and run the application.
"""
# Mac OS X passes arguments like '-psn_XXXX' to gui application.
# This argument is process serial number. However, this causes
# conflict with other OpenLP arguments. Since we do not use this
# argument we can delete it to avoid any potential conflicts.
# Mac OS X passes arguments like '-psn_XXXX' to the application. This argument is actually a process serial number.
# However, this causes a conflict with other OpenLP arguments. Since we do not use this argument we can delete it
# to avoid any potential conflicts.
if sys.platform.startswith('darwin'):
sys.argv = [x for x in sys.argv if not x.startswith('-psn')]
main()

View File

@ -59,7 +59,7 @@ __all__ = ['OpenLP', 'main']
log = logging.getLogger()
NT_REPAIR_STYLESHEET = """
WIN_REPAIR_STYLESHEET = """
QMainWindow::separator
{
border: none;
@ -127,7 +127,7 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
'QTableWidget, QListWidget, QTreeWidget {alternate-background-color: ' + base_color.name() + ';}\n'
application_stylesheet += alternate_rows_repair_stylesheet
if is_win():
application_stylesheet += NT_REPAIR_STYLESHEET
application_stylesheet += WIN_REPAIR_STYLESHEET
if application_stylesheet:
self.setStyleSheet(application_stylesheet)
show_splash = Settings().value('core/show splash')

View File

@ -33,6 +33,7 @@ import logging
import inspect
from openlp.core.common import trace_error_handler
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event', 'on_controller_size_changed',
'preview_size_changed', 'resizeEvent']
@ -41,11 +42,8 @@ class OpenLPMixin(object):
"""
Base Calling object for OpenLP classes.
"""
def __init__(self, parent):
try:
super(OpenLPMixin, self).__init__(parent)
except TypeError:
super(OpenLPMixin, self).__init__()
def __init__(self, *args, **kwargs):
super(OpenLPMixin, self).__init__(*args, **kwargs)
self.logger = logging.getLogger("%s.%s" % (self.__module__, self.__class__.__name__))
if self.logger.getEffectiveLevel() == logging.DEBUG:
for name, m in inspect.getmembers(self, inspect.ismethod):

View File

@ -33,7 +33,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry, UiStrings, translate
from openlp.core.common import Registry, UiStrings, translate, is_macosx
from openlp.core.lib import build_icon
from openlp.core.utils.actions import ActionList
@ -247,6 +247,8 @@ def create_action(parent, name, **kwargs):
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
if is_macosx():
action.setIconVisibleInMenu(False)
if kwargs.get('text'):
action.setText(kwargs.pop('text'))
if kwargs.get('icon'):

View File

@ -387,17 +387,21 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard, RegistryProperties):
self.progress_bar.setValue(self.progress_bar.maximum())
if self.has_run_wizard:
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
'Download complete. Click the finish button to return to OpenLP.'))
'Download complete. Click the %s button to return to OpenLP.') %
self.buttonText(QtGui.QWizard.FinishButton))
else:
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
'Download complete. Click the finish button to start OpenLP.'))
'Download complete. Click the %s button to start OpenLP.') %
self.buttonText(QtGui.QWizard.FinishButton))
else:
if self.has_run_wizard:
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
'Click the finish button to return to OpenLP.'))
'Click the %s button to return to OpenLP.') %
self.buttonText(QtGui.QWizard.FinishButton))
else:
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
'Click the finish button to start OpenLP.'))
'Click the %s button to start OpenLP.') %
self.buttonText(QtGui.QWizard.FinishButton))
self.finish_button.setVisible(True)
self.finish_button.setEnabled(True)
self.cancel_button.setVisible(False)

View File

@ -31,9 +31,7 @@ The UI widgets for the first time wizard.
"""
from PyQt4 import QtCore, QtGui
import sys
from openlp.core.common import translate
from openlp.core.common import translate, is_macosx
from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page
@ -64,9 +62,12 @@ class Ui_FirstTimeWizard(object):
first_time_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
first_time_wizard.resize(550, 386)
first_time_wizard.setModal(True)
first_time_wizard.setWizardStyle(QtGui.QWizard.ModernStyle)
first_time_wizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage | QtGui.QWizard.HaveCustomButton1)
if is_macosx():
first_time_wizard.setPixmap(QtGui.QWizard.BackgroundPixmap,
QtGui.QPixmap(':/wizards/openlp-osx-wizard.png'))
first_time_wizard.resize(634, 386)
self.finish_button = self.button(QtGui.QWizard.FinishButton)
self.no_internet_finish_button = self.button(QtGui.QWizard.CustomButton1)
self.cancel_button = self.button(QtGui.QWizard.CancelButton)
@ -212,7 +213,8 @@ class Ui_FirstTimeWizard(object):
translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard'))
self.information_label.setText(
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
'Click the next button below to start.'))
'Click the %s button below to start.') %
self.buttonText(QtGui.QWizard.NextButton))
self.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins'))
self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. '))
self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
@ -236,7 +238,7 @@ class Ui_FirstTimeWizard(object):
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.')
self.cancelWizardText = translate('OpenLP.FirstTimeWizard',
'\n\nTo cancel the First Time Wizard completely (and not start OpenLP), '
'click the Cancel button now.')
'click the %s button now.') % self.buttonText(QtGui.QWizard.CancelButton)
self.songs_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs'))
self.songs_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.'))
self.bibles_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles'))

View File

@ -60,6 +60,12 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont
"""
super(FormattingTagForm, self).__init__(parent)
self.setupUi(self)
self._setup()
def _setup(self):
"""
Set up the class. This method is mocked out by the tests.
"""
self.services = FormattingTagController()
self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected)
self.new_button.clicked.connect(self.on_new_clicked)

View File

@ -92,6 +92,8 @@ class Ui_MainWindow(object):
main_window.setObjectName('MainWindow')
main_window.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
main_window.setDockNestingEnabled(True)
if is_macosx():
main_window.setDocumentMode(True)
# Set up the main container, which contains all the other form widgets.
self.main_content = QtGui.QWidget(main_window)
self.main_content.setObjectName('main_content')
@ -118,10 +120,12 @@ class Ui_MainWindow(object):
self.recent_files_menu = QtGui.QMenu(self.file_menu)
self.recent_files_menu.setObjectName('recentFilesMenu')
self.file_import_menu = QtGui.QMenu(self.file_menu)
self.file_import_menu.setIcon(build_icon(u':/general/general_import.png'))
if not is_macosx():
self.file_import_menu.setIcon(build_icon(u':/general/general_import.png'))
self.file_import_menu.setObjectName('file_import_menu')
self.file_export_menu = QtGui.QMenu(self.file_menu)
self.file_export_menu.setIcon(build_icon(u':/general/general_export.png'))
if not is_macosx():
self.file_export_menu.setIcon(build_icon(u':/general/general_export.png'))
self.file_export_menu.setObjectName('file_export_menu')
# View Menu
self.view_menu = QtGui.QMenu(self.menu_bar)

View File

@ -31,7 +31,7 @@ The Create/Edit theme wizard
"""
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.common import UiStrings, translate, is_macosx
from openlp.core.lib import build_icon
from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
@ -41,19 +41,21 @@ class Ui_ThemeWizard(object):
"""
The Create/Edit theme wizard
"""
def setupUi(self, themeWizard):
def setupUi(self, theme_wizard):
"""
Set up the UI
"""
themeWizard.setObjectName('OpenLP.ThemeWizard')
themeWizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
themeWizard.setModal(True)
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.HaveCustomButton1)
theme_wizard.setObjectName('OpenLP.ThemeWizard')
theme_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
theme_wizard.setModal(True)
theme_wizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.HaveCustomButton1)
if is_macosx():
theme_wizard.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png'))
theme_wizard.resize(646, 400)
self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page
add_welcome_page(themeWizard, ':/wizards/wizard_createtheme.bmp')
add_welcome_page(theme_wizard, ':/wizards/wizard_createtheme.bmp')
# Background Page
self.background_page = QtGui.QWizardPage()
self.background_page.setObjectName('background_page')
@ -137,7 +139,7 @@ class Ui_ThemeWizard(object):
self.transparent_layout.setObjectName('Transparent_layout')
self.background_stack.addWidget(self.transparent_widget)
self.background_layout.addLayout(self.background_stack)
themeWizard.addPage(self.background_page)
theme_wizard.addPage(self.background_page)
# Main Area Page
self.main_area_page = QtGui.QWizardPage()
self.main_area_page.setObjectName('main_area_page')
@ -218,7 +220,7 @@ class Ui_ThemeWizard(object):
self.shadow_size_spin_box.setObjectName('shadow_size_spin_box')
self.shadow_layout.addWidget(self.shadow_size_spin_box)
self.main_area_layout.addRow(self.shadow_check_box, self.shadow_layout)
themeWizard.addPage(self.main_area_page)
theme_wizard.addPage(self.main_area_page)
# Footer Area Page
self.footer_area_page = QtGui.QWizardPage()
self.footer_area_page.setObjectName('footer_area_page')
@ -242,7 +244,7 @@ class Ui_ThemeWizard(object):
self.footer_size_spin_box.setObjectName('FooterSizeSpinBox')
self.footer_area_layout.addRow(self.footer_size_label, self.footer_size_spin_box)
self.footer_area_layout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
themeWizard.addPage(self.footer_area_page)
theme_wizard.addPage(self.footer_area_page)
# Alignment Page
self.alignment_page = QtGui.QWizardPage()
self.alignment_page.setObjectName('alignment_page')
@ -264,7 +266,7 @@ class Ui_ThemeWizard(object):
self.transitions_check_box.setObjectName('transitions_check_box')
self.alignment_layout.addRow(self.transitions_label, self.transitions_check_box)
self.alignment_layout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
themeWizard.addPage(self.alignment_page)
theme_wizard.addPage(self.alignment_page)
# Area Position Page
self.area_position_page = QtGui.QWizardPage()
self.area_position_page.setObjectName('area_position_page')
@ -334,7 +336,7 @@ class Ui_ThemeWizard(object):
self.footer_height_spin_box.setObjectName('footer_height_spin_box')
self.footer_position_layout.addRow(self.footer_height_label, self.footer_height_spin_box)
self.area_position_layout.addWidget(self.footer_position_group_box)
themeWizard.addPage(self.area_position_page)
theme_wizard.addPage(self.area_position_page)
# Preview Page
self.preview_page = QtGui.QWizardPage()
self.preview_page.setObjectName('preview_page')
@ -362,8 +364,8 @@ class Ui_ThemeWizard(object):
self.preview_box_label.setObjectName('preview_box_label')
self.preview_area_layout.addWidget(self.preview_box_label)
self.preview_layout.addWidget(self.preview_area)
themeWizard.addPage(self.preview_page)
self.retranslateUi(themeWizard)
theme_wizard.addPage(self.preview_page)
self.retranslateUi(theme_wizard)
QtCore.QObject.connect(self.background_combo_box, QtCore.SIGNAL('currentIndexChanged(int)'),
self.background_stack, QtCore.SLOT('setCurrentIndex(int)'))
QtCore.QObject.connect(self.outline_check_box, QtCore.SIGNAL('toggled(bool)'), self.outline_color_button,
@ -391,11 +393,11 @@ class Ui_ThemeWizard(object):
QtCore.QObject.connect(self.footer_position_check_box, QtCore.SIGNAL('toggled(bool)'),
self.footer_height_spin_box, QtCore.SLOT('setDisabled(bool)'))
def retranslateUi(self, themeWizard):
def retranslateUi(self, theme_wizard):
"""
Translate the UI on the fly
"""
themeWizard.setWindowTitle(translate('OpenLP.ThemeWizard', 'Theme Wizard'))
theme_wizard.setWindowTitle(translate('OpenLP.ThemeWizard', 'Theme Wizard'))
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard'))
self.information_label.setText(
@ -484,8 +486,8 @@ class Ui_ThemeWizard(object):
self.footer_height_label.setText(translate('OpenLP.ThemeWizard', 'Height:'))
self.footer_height_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.footer_position_check_box.setText(translate('OpenLP.ThemeWizard', 'Use default location'))
themeWizard.setOption(QtGui.QWizard.HaveCustomButton1, False)
themeWizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.ThemeWizard', 'Layout Preview'))
theme_wizard.setOption(QtGui.QWizard.HaveCustomButton1, False)
theme_wizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.ThemeWizard', 'Layout Preview'))
self.preview_page.setTitle(translate('OpenLP.ThemeWizard', 'Preview and Save'))
self.preview_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Preview the theme and save it.'))
self.theme_name_label.setText(translate('OpenLP.ThemeWizard', 'Theme name:'))

View File

@ -34,7 +34,7 @@ import os
from PyQt4 import QtGui
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate, is_macosx
from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page
@ -121,9 +121,10 @@ class OpenLPWizard(QtGui.QWizard, RegistryProperties):
"""
self.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.setModal(True)
self.setWizardStyle(QtGui.QWizard.ModernStyle)
self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage)
if is_macosx():
self.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png'))
add_welcome_page(self, image)
self.add_custom_pages()
if self.with_progress_page:

View File

@ -99,6 +99,7 @@
<file>export_load.png</file>
</qresource>
<qresource prefix="wizards">
<file>openlp-osx-wizard.png</file>
<file>wizard_exportsong.bmp</file>
<file>wizard_importsong.bmp</file>
<file>wizard_importbible.bmp</file>
@ -151,10 +152,10 @@
<file>messagebox_warning.png</file>
</qresource>
<qresource prefix="remote">
<file>network_server.png</file>
<file>network_server.png</file>
<file>network_ssl.png</file>
<file>network_auth.png</file>
</qresource>
<file>network_auth.png</file>
</qresource>
<qresource prefix="songusage">
<file>song_usage_active.png</file>
<file>song_usage_inactive.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -51,7 +51,7 @@ class TestTheme(TestCase):
"""
pass
def test_new_theme(self):
def new_theme_test(self):
"""
Test the theme creation - basic test
"""

View File

@ -29,10 +29,14 @@
"""
Package to test the openlp.core.lib.ui package.
"""
from PyQt4 import QtGui
from PyQt4 import QtCore, QtGui
from unittest import TestCase
from openlp.core.lib.ui import *
from openlp.core.common import UiStrings, translate
from openlp.core.lib.ui import add_welcome_page, create_button_box, create_horizontal_adjusting_combo_box, \
create_button, create_action, create_valign_selection_widgets, find_and_set_in_combo_box, create_widget_action, \
set_case_insensitive_completer
from tests.functional import MagicMock, patch
class TestUi(TestCase):
@ -40,7 +44,7 @@ class TestUi(TestCase):
Test the functions in the ui module
"""
def test_add_welcome_page(self):
def add_welcome_page_test(self):
"""
Test appending a welcome page to a wizard
"""
@ -54,7 +58,7 @@ class TestUi(TestCase):
self.assertEqual(1, len(wizard.pageIds()), 'The wizard should have one page.')
self.assertIsInstance(wizard.page(0).pixmap(QtGui.QWizard.WatermarkPixmap), QtGui.QPixmap)
def test_create_button_box(self):
def create_button_box_test(self):
"""
Test creating a button box for a dialog
"""
@ -82,7 +86,7 @@ class TestUi(TestCase):
self.assertEqual(1, len(btnbox.buttons()))
self.assertEqual(QtGui.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0]))
def test_create_horizontal_adjusting_combo_box(self):
def create_horizontal_adjusting_combo_box_test(self):
"""
Test creating a horizontal adjusting combo box
"""
@ -97,7 +101,7 @@ class TestUi(TestCase):
self.assertEqual('combo1', combo.objectName())
self.assertEqual(QtGui.QComboBox.AdjustToMinimumContentsLength, combo.sizeAdjustPolicy())
def test_create_button(self):
def create_button_test(self):
"""
Test creating a button
"""
@ -129,7 +133,7 @@ class TestUi(TestCase):
self.assertEqual('my_btn', btn.objectName())
self.assertTrue(btn.isEnabled())
def test_create_action(self):
def create_action_test(self):
"""
Test creating an action
"""
@ -154,7 +158,44 @@ class TestUi(TestCase):
self.assertEqual('my tooltip', action.toolTip())
self.assertEqual('my statustip', action.statusTip())
def test_create_checked_enabled_visible_action(self):
def create_action_on_mac_osx_test(self):
"""
Test creating an action on OS X calls the correct method
"""
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
patch('openlp.core.lib.ui.QtGui.QAction') as MockedQAction:
mocked_is_macosx.return_value = True
mocked_action = MagicMock()
MockedQAction.return_value = mocked_action
dialog = QtGui.QDialog()
# WHEN: An action is created
create_action(dialog, 'my_action')
# THEN: setIconVisibleInMenu should be called
mocked_action.setIconVisibleInMenu.assert_called_with(False)
def create_action_not_on_mac_osx_test(self):
"""
Test creating an action on something other than OS X doesn't call the method
"""
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
patch('openlp.core.lib.ui.QtGui.QAction') as MockedQAction:
mocked_is_macosx.return_value = False
mocked_action = MagicMock()
MockedQAction.return_value = mocked_action
dialog = QtGui.QDialog()
# WHEN: An action is created
create_action(dialog, 'my_action')
# THEN: setIconVisibleInMenu should not be called
self.assertEqual(0, mocked_action.setIconVisibleInMenu.call_count,
'setIconVisibleInMenu should not have been called')
def create_checked_enabled_visible_action_test(self):
"""
Test creating an action with the 'checked', 'enabled' and 'visible' properties.
"""
@ -169,7 +210,7 @@ class TestUi(TestCase):
self.assertEqual(False, action.isEnabled())
self.assertEqual(False, action.isVisible())
def test_create_valign_selection_widgets(self):
def create_valign_selection_widgets_test(self):
"""
Test creating a combo box for valign selection
"""
@ -186,7 +227,7 @@ class TestUi(TestCase):
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
self.assertTrue(combo.findText(text) >= 0)
def test_find_and_set_in_combo_box(self):
def find_and_set_in_combo_box_test(self):
"""
Test finding a string in a combo box and setting it as the selected item if present
"""
@ -213,7 +254,7 @@ class TestUi(TestCase):
# THEN: The index should have changed
self.assertEqual(2, combo.currentIndex())
def test_create_widget_action(self):
def create_widget_action_test(self):
"""
Test creating an action for a widget
"""
@ -227,7 +268,7 @@ class TestUi(TestCase):
self.assertIsInstance(action, QtGui.QAction)
self.assertEqual(action.objectName(), 'some action')
def test_set_case_insensitive_completer(self):
def set_case_insensitive_completer_test(self):
"""
Test setting a case insensitive completer on a widget
"""

View File

@ -47,7 +47,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
Registry().register('application', self.app)
self.first_time_form = FirstTimeForm(screens)
def test_access_to_config(self):
def access_to_config_test(self):
"""
Test if we can access the First Time Form's config file
"""
@ -59,7 +59,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
self.assertTrue(self.first_time_form.web_access,
'First Time Wizard\'s web configuration file should be available')
def test_parsable_config(self):
def parsable_config_test(self):
"""
Test if the First Time Form's config file is parsable
"""

View File

@ -39,7 +39,7 @@ class TestFormattingTagController(TestCase):
def setUp(self):
self.services = FormattingTagController()
def test_strip(self):
def strip_test(self):
"""
Test that the _strip strips the correct chars
"""
@ -52,7 +52,7 @@ class TestFormattingTagController(TestCase):
# THEN: The tag should be returned with the wrappers removed.
self.assertEqual(result, 'tag', 'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'')
def test_end_tag_changed_processes_correctly(self):
def end_tag_changed_processes_correctly_test(self):
"""
Test that the end html tags are generated correctly
"""
@ -77,7 +77,7 @@ class TestFormattingTagController(TestCase):
self.assertTrue(error == test['valid'], 'Function should not generate unexpected error messages : %s ' %
error)
def test_start_tag_changed_processes_correctly(self):
def start_tag_changed_processes_correctly_test(self):
"""
Test that the end html tags are generated correctly
"""
@ -100,7 +100,7 @@ class TestFormattingTagController(TestCase):
self.assertTrue(error == test['valid'], 'Function should not generate unexpected error messages : %s ' %
error)
def test_start_html_to_end_html(self):
def start_html_to_end_html_test(self):
"""
Test that the end html tags are generated correctly
"""

View File

@ -29,17 +29,17 @@
"""
Package to test the openlp.core.ui.formattingtagsform package.
"""
from PyQt4 import QtGui
from unittest import TestCase
from openlp.core.common import translate
from tests.functional import MagicMock, patch
from tests.functional import MagicMock, patch, call
from openlp.core.ui.formattingtagform import FormattingTagForm
# TODO: Tests Still TODO
# __init__
# exec_
# on_new_clicked
# on_delete_clicked
# on_saved_clicked
# _reloadTable
@ -47,30 +47,60 @@ from openlp.core.ui.formattingtagform import FormattingTagForm
class TestFormattingTagForm(TestCase):
def setUp(self):
self.init_patcher = patch('openlp.core.ui.formattingtagform.FormattingTagForm.__init__')
self.qdialog_patcher = patch('openlp.core.ui.formattingtagform.QtGui.QDialog')
self.ui_formatting_tag_dialog_patcher = patch('openlp.core.ui.formattingtagform.Ui_FormattingTagDialog')
self.mocked_init = self.init_patcher.start()
self.mocked_qdialog = self.qdialog_patcher.start()
self.mocked_ui_formatting_tag_dialog = self.ui_formatting_tag_dialog_patcher.start()
self.mocked_init.return_value = None
"""
Mock out stuff for all the tests
"""
self.setup_patcher = patch('openlp.core.ui.formattingtagform.FormattingTagForm._setup')
self.setup_patcher.start()
def tearDown(self):
self.init_patcher.stop()
self.qdialog_patcher.stop()
self.ui_formatting_tag_dialog_patcher.stop()
def test_on_text_edited(self):
"""
Test that the appropriate actions are preformed when on_text_edited is called
Remove the mocks
"""
self.setup_patcher.stop()
def on_row_selected_test(self):
"""
Test that the appropriate actions are preformed when on_row_selected is called
"""
# GIVEN: An instance of the Formatting Tag Form and a mocked delete_button
form = FormattingTagForm(None)
form.delete_button = MagicMock()
# WHEN: on_row_selected is called
form.on_row_selected()
# THEN: setEnabled and should have been called on delete_button
form.delete_button.setEnabled.assert_called_with(True)
def on_new_clicked_test(self):
"""
Test that clicking the Add a new tag button does the right thing
"""
# GIVEN: An instance of the Formatting Tag Form and a mocked save_push_button
form = FormattingTagForm()
form.save_button = MagicMock()
# GIVEN: A formatting tag form and a mocked out tag table widget
form = FormattingTagForm(None)
form.tag_table_widget = MagicMock()
row_count = 5
form.tag_table_widget.rowCount.return_value = row_count
# WHEN: on_text_edited is called with an arbitrary value
# form.on_text_edited('text')
# WHEN: on_new_clicked is run (i.e. the Add new button was clicked)
with patch('openlp.core.ui.formattingtagform.QtGui.QTableWidgetItem') as MockedQTableWidgetItem:
mocked_table_widget = MagicMock()
MockedQTableWidgetItem.return_value = mocked_table_widget
form.on_new_clicked()
# THEN: setEnabled and setDefault should have been called on save_push_button
# form.save_button.setEnabled.assert_called_with(True)
# THEN: A new row should be added to the table
form.tag_table_widget.rowCount.assert_called_with()
form.tag_table_widget.insertRow.assert_called_with(row_count)
expected_set_item_calls = [
call(row_count, 0, mocked_table_widget),
call(row_count, 1, mocked_table_widget),
call(row_count, 2, mocked_table_widget),
call(row_count, 3, mocked_table_widget)
]
self.assertEqual(expected_set_item_calls, form.tag_table_widget.setItem.call_args_list,
'setItem should have been called correctly')
form.tag_table_widget.resizeRowsToContents.assert_called_with()
form.tag_table_widget.scrollToBottom.assert_called_with()
form.tag_table_widget.selectRow.assert_called_with(row_count)