forked from openlp/openlp
Merge branch 'refactor-theme-wizard-ui' into 'master'
Refactor theme wizard ui into separate pages See merge request openlp/openlp!99
This commit is contained in:
commit
6e3b702660
@ -214,6 +214,20 @@ class HorizontalType(object):
|
||||
|
||||
Names = ['left', 'right', 'center', 'justify']
|
||||
|
||||
@staticmethod
|
||||
def to_string(align):
|
||||
"""
|
||||
Return a string representation of the alignment
|
||||
"""
|
||||
return HorizontalType.Names[align]
|
||||
|
||||
@staticmethod
|
||||
def from_string(align):
|
||||
"""
|
||||
Return an alignment for a given string
|
||||
"""
|
||||
return HorizontalType.Names.index(align)
|
||||
|
||||
|
||||
class VerticalType(object):
|
||||
"""
|
||||
@ -225,6 +239,20 @@ class VerticalType(object):
|
||||
|
||||
Names = ['top', 'middle', 'bottom']
|
||||
|
||||
@staticmethod
|
||||
def to_string(align):
|
||||
"""
|
||||
Return a string representation of the alignment
|
||||
"""
|
||||
return VerticalType.Names[align]
|
||||
|
||||
@staticmethod
|
||||
def from_string(align):
|
||||
"""
|
||||
Return an alignment for a given string
|
||||
"""
|
||||
return VerticalType.Names.index(align)
|
||||
|
||||
|
||||
BOOLEAN_LIST = ['bold', 'italics', 'override', 'outline', 'shadow', 'slide_transition']
|
||||
|
||||
|
@ -31,6 +31,7 @@ from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.labels import FormLabel
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -306,7 +307,7 @@ def create_valign_selection_widgets(parent):
|
||||
|
||||
:param parent: The parent object. This should be a ``QWidget`` descendant.
|
||||
"""
|
||||
label = QtWidgets.QLabel(parent)
|
||||
label = FormLabel(parent)
|
||||
label.setText(translate('OpenLP.Ui', '&Vertical Align:'))
|
||||
combo_box = QtWidgets.QComboBox(parent)
|
||||
combo_box.addItems([UiStrings().Top, UiStrings().Middle, UiStrings().Bottom])
|
||||
|
61
openlp/core/pages/__init__.py
Normal file
61
openlp/core/pages/__init__.py
Normal file
@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.pages` module contains wizard pages used in OpenLP
|
||||
"""
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
|
||||
class GridLayoutPage(QtWidgets.QWizardPage):
|
||||
"""
|
||||
A class that has a QGridLayout for its layout which automatically ensure all columns are equal width
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._column_width = 0
|
||||
self.layout = QtWidgets.QGridLayout(self)
|
||||
self.setup_ui()
|
||||
self.retranslate_ui()
|
||||
self.resize_columns()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
"""
|
||||
Override inherited resize method
|
||||
"""
|
||||
super().resizeEvent(event)
|
||||
self.resize_columns()
|
||||
|
||||
def resize_columns(self):
|
||||
"""
|
||||
Resize all the column widths
|
||||
"""
|
||||
width = self.layout.contentsRect().width()
|
||||
spacing = self.layout.horizontalSpacing()
|
||||
column_count = self.layout.columnCount()
|
||||
self._column_width = (width - (spacing * (column_count - 1))) // column_count
|
||||
for column_number in range(column_count):
|
||||
self.layout.setColumnMinimumWidth(column_number, self._column_width)
|
||||
|
||||
def setup_ui(self):
|
||||
raise NotImplementedError('Descendant pages need to implement setup_ui')
|
||||
|
||||
def retranslate_ui(self):
|
||||
raise NotImplementedError('Descendant pages need to implement retranslate_ui')
|
169
openlp/core/pages/alignment.py
Normal file
169
openlp/core/pages/alignment.py
Normal file
@ -0,0 +1,169 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.pages.alignment` module contains the alignment page used in the theme wizard
|
||||
"""
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib.theme import HorizontalType, VerticalType, TransitionType, TransitionSpeed
|
||||
from openlp.core.lib.ui import create_valign_selection_widgets
|
||||
from openlp.core.pages import GridLayoutPage
|
||||
from openlp.core.widgets.labels import FormLabel
|
||||
|
||||
|
||||
class AlignmentTransitionsPage(GridLayoutPage):
|
||||
"""
|
||||
A widget containing the alignment and transitions options
|
||||
"""
|
||||
def setup_ui(self):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
# Alignment
|
||||
self.horizontal_label = FormLabel(self)
|
||||
self.horizontal_label.setObjectName('horizontal_label')
|
||||
self.layout.addWidget(self.horizontal_label, 0, 0)
|
||||
self.horizontal_combo_box = QtWidgets.QComboBox(self)
|
||||
self.horizontal_combo_box.addItems(['', '', '', ''])
|
||||
self.horizontal_combo_box.setObjectName('horizontal_combo_box')
|
||||
self.layout.addWidget(self.horizontal_combo_box, 0, 1, 1, 3)
|
||||
self.vertical_label, self.vertical_combo_box = create_valign_selection_widgets(self)
|
||||
self.vertical_label.setObjectName('vertical_label')
|
||||
self.layout.addWidget(self.vertical_label, 1, 0)
|
||||
self.vertical_combo_box.setObjectName('vertical_combo_box')
|
||||
self.layout.addWidget(self.vertical_combo_box, 1, 1, 1, 3)
|
||||
# Line
|
||||
self.line = QtWidgets.QFrame(self)
|
||||
self.line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.line.setObjectName('line')
|
||||
self.layout.addWidget(self.line, 2, 0, 1, 4)
|
||||
# Transitions
|
||||
self.transitions_enabled_check_box = QtWidgets.QCheckBox(self)
|
||||
self.transitions_enabled_check_box.setObjectName('transitions_enabled_check_box')
|
||||
self.layout.addWidget(self.transitions_enabled_check_box, 3, 1)
|
||||
self.transition_effect_label = FormLabel(self)
|
||||
self.transition_effect_label.setObjectName('transition_effect_label')
|
||||
self.layout.addWidget(self.transition_effect_label, 4, 0)
|
||||
self.transition_effect_combo_box = QtWidgets.QComboBox(self)
|
||||
self.transition_effect_combo_box.setObjectName('transition_effect_combo_box')
|
||||
self.transition_effect_combo_box.addItems(['', '', '', '', ''])
|
||||
self.layout.addWidget(self.transition_effect_combo_box, 4, 1)
|
||||
self.transition_speed_label = FormLabel(self)
|
||||
self.transition_speed_label.setObjectName('transition_speed_label')
|
||||
self.layout.addWidget(self.transition_speed_label, 4, 2)
|
||||
self.transition_speed_combo_box = QtWidgets.QComboBox(self)
|
||||
self.transition_speed_combo_box.setObjectName('transition_speed_combo_box')
|
||||
self.transition_speed_combo_box.addItems(['', '', ''])
|
||||
self.layout.addWidget(self.transition_speed_combo_box, 4, 3)
|
||||
# Connect slots
|
||||
self.transitions_enabled_check_box.stateChanged.connect(self._on_transition_enabled_changed)
|
||||
|
||||
def retranslate_ui(self):
|
||||
"""
|
||||
Translate the widgets
|
||||
"""
|
||||
self.horizontal_label.setText(translate('OpenLP.ThemeWizard', 'Horizontal Align:'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Left, translate('OpenLP.ThemeWizard', 'Left'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Right, translate('OpenLP.ThemeWizard', 'Right'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Center, translate('OpenLP.ThemeWizard', 'Center'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Justify, translate('OpenLP.ThemeWizard', 'Justify'))
|
||||
self.transitions_enabled_check_box.setText(translate('OpenLP.ThemeWizard', 'Enable transitions'))
|
||||
self.transition_effect_label.setText(translate('OpenLP.ThemeWizard', 'Effect:'))
|
||||
self.transition_effect_combo_box.setItemText(TransitionType.Fade, translate('OpenLP.ThemeWizard', 'Fade'))
|
||||
self.transition_effect_combo_box.setItemText(TransitionType.Slide, translate('OpenLP.ThemeWizard', 'Slide'))
|
||||
self.transition_effect_combo_box.setItemText(TransitionType.Concave, translate('OpenLP.ThemeWizard', 'Concave'))
|
||||
self.transition_effect_combo_box.setItemText(TransitionType.Convex, translate('OpenLP.ThemeWizard', 'Convex'))
|
||||
self.transition_effect_combo_box.setItemText(TransitionType.Zoom, translate('OpenLP.ThemeWizard', 'Zoom'))
|
||||
self.transition_speed_label.setText(translate('OpenLP.ThemeWizard', 'Speed:'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Normal, translate('OpenLP.ThemeWizard', 'Normal'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Fast, translate('OpenLP.ThemeWizard', 'Fast'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Slow, translate('OpenLP.ThemeWizard', 'Slow'))
|
||||
|
||||
def _on_transition_enabled_changed(self, value):
|
||||
"""
|
||||
Update the UI widgets when the transition is enabled or disabled
|
||||
"""
|
||||
self.transition_effect_label.setEnabled(value)
|
||||
self.transition_effect_combo_box.setEnabled(value)
|
||||
self.transition_speed_label.setEnabled(value)
|
||||
self.transition_speed_combo_box.setEnabled(value)
|
||||
|
||||
@property
|
||||
def horizontal_align(self):
|
||||
return self.horizontal_combo_box.currentIndex()
|
||||
|
||||
@horizontal_align.setter
|
||||
def horizontal_align(self, value):
|
||||
if isinstance(value, str):
|
||||
self.horizontal_combo_box.setCurrentIndex(HorizontalType.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.horizontal_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('horizontal_align must either be a string or an int')
|
||||
|
||||
@property
|
||||
def vertical_align(self):
|
||||
return self.vertical_combo_box.currentIndex()
|
||||
|
||||
@vertical_align.setter
|
||||
def vertical_align(self, value):
|
||||
if isinstance(value, str):
|
||||
self.vertical_combo_box.setCurrentIndex(VerticalType.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.vertical_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('vertical_align must either be a string or an int')
|
||||
|
||||
@property
|
||||
def is_transition_enabled(self):
|
||||
return self.transitions_enabled_check_box.isChecked()
|
||||
|
||||
@is_transition_enabled.setter
|
||||
def is_transition_enabled(self, value):
|
||||
self.transitions_enabled_check_box.setChecked(value)
|
||||
self._on_transition_enabled_changed(value)
|
||||
|
||||
@property
|
||||
def transition_type(self):
|
||||
return self.transition_effect_combo_box.currentIndex()
|
||||
|
||||
@transition_type.setter
|
||||
def transition_type(self, value):
|
||||
if isinstance(value, str):
|
||||
self.transition_effect_combo_box.setCurrentIndex(TransitionType.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.transition_effect_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('transition_type must either be a string or an int')
|
||||
|
||||
@property
|
||||
def transition_speed(self):
|
||||
return self.transition_speed_combo_box.currentIndex()
|
||||
|
||||
@transition_speed.setter
|
||||
def transition_speed(self, value):
|
||||
if isinstance(value, str):
|
||||
self.transition_speed_combo_box.setCurrentIndex(TransitionSpeed.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.transition_speed_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('transition_speed must either be a string or an int')
|
226
openlp/core/pages/areaposition.py
Normal file
226
openlp/core/pages/areaposition.py
Normal file
@ -0,0 +1,226 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.pages.areaposition` module contains the area position page used in the theme wizard
|
||||
"""
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.pages import GridLayoutPage
|
||||
from openlp.core.widgets.labels import FormLabel
|
||||
|
||||
|
||||
class AreaPositionPage(GridLayoutPage):
|
||||
"""
|
||||
A wizard page for the area positioning widgets in the theme wizard
|
||||
"""
|
||||
def setup_ui(self):
|
||||
"""
|
||||
Set up the UI
|
||||
"""
|
||||
# Main area position
|
||||
self.main_position_group_box = QtWidgets.QGroupBox(self)
|
||||
self.main_position_group_box.setObjectName('main_position_group_box')
|
||||
self.main_position_layout = QtWidgets.QGridLayout(self.main_position_group_box)
|
||||
self.main_position_layout.setObjectName('main_position_layout')
|
||||
self.main_position_check_box = QtWidgets.QCheckBox(self.main_position_group_box)
|
||||
self.main_position_check_box.setObjectName('main_position_check_box')
|
||||
self.main_position_layout.addWidget(self.main_position_check_box, 0, 0, 1, 2)
|
||||
self.main_x_label = FormLabel(self.main_position_group_box)
|
||||
self.main_x_label.setObjectName('main_x_label')
|
||||
self.main_position_layout.addWidget(self.main_x_label, 1, 0)
|
||||
self.main_x_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_x_spin_box.setMaximum(9999)
|
||||
self.main_x_spin_box.setObjectName('main_x_spin_box')
|
||||
self.main_position_layout.addWidget(self.main_x_spin_box, 1, 1)
|
||||
self.main_y_label = FormLabel(self.main_position_group_box)
|
||||
self.main_y_label.setObjectName('main_y_label')
|
||||
self.main_position_layout.addWidget(self.main_y_label, 2, 0)
|
||||
self.main_y_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_y_spin_box.setMaximum(9999)
|
||||
self.main_y_spin_box.setObjectName('main_y_spin_box')
|
||||
self.main_position_layout.addWidget(self.main_y_spin_box, 2, 1)
|
||||
self.main_width_label = FormLabel(self.main_position_group_box)
|
||||
self.main_width_label.setObjectName('main_width_label')
|
||||
self.main_width_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_width_spin_box.setMaximum(9999)
|
||||
self.main_width_spin_box.setObjectName('main_width_spin_box')
|
||||
self.main_position_layout.addWidget(self.main_width_label, 3, 0)
|
||||
self.main_position_layout.addWidget(self.main_width_spin_box, 3, 1)
|
||||
self.main_height_label = FormLabel(self.main_position_group_box)
|
||||
self.main_height_label.setObjectName('main_height_label')
|
||||
self.main_height_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_height_spin_box.setMaximum(9999)
|
||||
self.main_height_spin_box.setObjectName('main_height_spin_box')
|
||||
self.main_position_layout.addWidget(self.main_height_label, 4, 0)
|
||||
self.main_position_layout.addWidget(self.main_height_spin_box, 4, 1)
|
||||
self.layout.addWidget(self.main_position_group_box, 0, 0)
|
||||
# Footer area position
|
||||
self.footer_position_group_box = QtWidgets.QGroupBox(self)
|
||||
self.footer_position_group_box.setObjectName('footer_position_group_box')
|
||||
self.footer_position_layout = QtWidgets.QGridLayout(self.footer_position_group_box)
|
||||
self.footer_position_layout.setObjectName('footer_position_layout')
|
||||
self.footer_position_check_box = QtWidgets.QCheckBox(self.footer_position_group_box)
|
||||
self.footer_position_check_box.setObjectName('footer_position_check_box')
|
||||
self.footer_position_layout.addWidget(self.footer_position_check_box, 0, 0, 1, 2)
|
||||
self.footer_x_label = FormLabel(self.footer_position_group_box)
|
||||
self.footer_x_label.setObjectName('footer_x_label')
|
||||
self.footer_x_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_x_spin_box.setMaximum(9999)
|
||||
self.footer_x_spin_box.setObjectName('footer_x_spin_box')
|
||||
self.footer_position_layout.addWidget(self.footer_x_label, 1, 0)
|
||||
self.footer_position_layout.addWidget(self.footer_x_spin_box, 1, 1)
|
||||
self.footer_y_label = FormLabel(self.footer_position_group_box)
|
||||
self.footer_y_label.setObjectName('footer_y_label')
|
||||
self.footer_y_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_y_spin_box.setMaximum(9999)
|
||||
self.footer_y_spin_box.setObjectName('footer_y_spin_box')
|
||||
self.footer_position_layout.addWidget(self.footer_y_label, 2, 0)
|
||||
self.footer_position_layout.addWidget(self.footer_y_spin_box, 2, 1)
|
||||
self.footer_width_label = FormLabel(self.footer_position_group_box)
|
||||
self.footer_width_label.setObjectName('footer_width_label')
|
||||
self.footer_width_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_width_spin_box.setMaximum(9999)
|
||||
self.footer_width_spin_box.setObjectName('footer_width_spin_box')
|
||||
self.footer_position_layout.addWidget(self.footer_width_label, 3, 0)
|
||||
self.footer_position_layout.addWidget(self.footer_width_spin_box, 3, 1)
|
||||
self.footer_height_label = FormLabel(self.footer_position_group_box)
|
||||
self.footer_height_label.setObjectName('footer_height_label')
|
||||
self.footer_height_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_height_spin_box.setMaximum(9999)
|
||||
self.footer_height_spin_box.setObjectName('footer_height_spin_box')
|
||||
self.footer_position_layout.addWidget(self.footer_height_label, 4, 0)
|
||||
self.footer_position_layout.addWidget(self.footer_height_spin_box, 4, 1)
|
||||
self.layout.addWidget(self.footer_position_group_box, 0, 1)
|
||||
# Connect signals to slots
|
||||
self.main_position_check_box.toggled.connect(self.main_x_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_y_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_width_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_height_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_x_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_y_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_width_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_height_spin_box.setDisabled)
|
||||
|
||||
def retranslate_ui(self):
|
||||
"""
|
||||
Translate the UI
|
||||
"""
|
||||
self.main_position_group_box.setTitle(translate('OpenLP.ThemeWizard', '&Main Area'))
|
||||
self.main_position_check_box.setText(translate('OpenLP.ThemeWizard', '&Use default location'))
|
||||
self.main_x_label.setText(translate('OpenLP.ThemeWizard', 'X position:'))
|
||||
self.main_x_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_y_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_y_label.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
|
||||
self.main_width_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_width_label.setText(translate('OpenLP.ThemeWizard', 'Width:'))
|
||||
self.main_height_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_height_label.setText(translate('OpenLP.ThemeWizard', 'Height:'))
|
||||
self.footer_position_group_box.setTitle(translate('OpenLP.ThemeWizard', '&Footer Area'))
|
||||
self.footer_x_label.setText(translate('OpenLP.ThemeWizard', 'X position:'))
|
||||
self.footer_x_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.footer_y_label.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
|
||||
self.footer_y_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.footer_width_label.setText(translate('OpenLP.ThemeWizard', 'Width:'))
|
||||
self.footer_width_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
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'))
|
||||
|
||||
@property
|
||||
def use_main_default_location(self):
|
||||
return self.main_position_check_box.isChecked()
|
||||
|
||||
@use_main_default_location.setter
|
||||
def use_main_default_location(self, value):
|
||||
self.main_position_check_box.setChecked(value)
|
||||
|
||||
@property
|
||||
def main_x(self):
|
||||
return self.main_x_spin_box.value()
|
||||
|
||||
@main_x.setter
|
||||
def main_x(self, value):
|
||||
self.main_x_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def main_y(self):
|
||||
return self.main_y_spin_box.value()
|
||||
|
||||
@main_y.setter
|
||||
def main_y(self, value):
|
||||
self.main_y_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def main_width(self):
|
||||
return self.main_width_spin_box.value()
|
||||
|
||||
@main_width.setter
|
||||
def main_width(self, value):
|
||||
self.main_width_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def main_height(self):
|
||||
return self.main_height_spin_box.value()
|
||||
|
||||
@main_height.setter
|
||||
def main_height(self, value):
|
||||
self.main_height_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def use_footer_default_location(self):
|
||||
return self.footer_position_check_box.isChecked()
|
||||
|
||||
@use_footer_default_location.setter
|
||||
def use_footer_default_location(self, value):
|
||||
self.footer_position_check_box.setChecked(value)
|
||||
|
||||
@property
|
||||
def footer_x(self):
|
||||
return self.footer_x_spin_box.value()
|
||||
|
||||
@footer_x.setter
|
||||
def footer_x(self, value):
|
||||
self.footer_x_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def footer_y(self):
|
||||
return self.footer_y_spin_box.value()
|
||||
|
||||
@footer_y.setter
|
||||
def footer_y(self, value):
|
||||
self.footer_y_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def footer_width(self):
|
||||
return self.footer_width_spin_box.value()
|
||||
|
||||
@footer_width.setter
|
||||
def footer_width(self, value):
|
||||
self.footer_width_spin_box.setValue(value)
|
||||
|
||||
@property
|
||||
def footer_height(self):
|
||||
return self.footer_height_spin_box.value()
|
||||
|
||||
@footer_height.setter
|
||||
def footer_height(self, value):
|
||||
self.footer_height_spin_box.setValue(value)
|
253
openlp/core/pages/background.py
Normal file
253
openlp/core/pages/background.py
Normal file
@ -0,0 +1,253 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.pages.background` module contains the background page used in the theme wizard
|
||||
"""
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common import get_images_filter
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib.theme import BackgroundGradientType, BackgroundType
|
||||
from openlp.core.pages import GridLayoutPage
|
||||
from openlp.core.ui.media import VIDEO_EXT
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
from openlp.core.widgets.edits import PathEdit
|
||||
from openlp.core.widgets.labels import FormLabel
|
||||
|
||||
|
||||
class BackgroundPage(GridLayoutPage):
|
||||
"""
|
||||
A background selection widget
|
||||
"""
|
||||
Color = 'color'
|
||||
Gradient = 'gradient'
|
||||
Image = 'image'
|
||||
Video = 'video'
|
||||
|
||||
def setup_ui(self):
|
||||
"""
|
||||
Set up the ui
|
||||
"""
|
||||
# background type
|
||||
self.background_label = FormLabel(self)
|
||||
self.background_label.setObjectName('background_label')
|
||||
self.layout.addWidget(self.background_label, 0, 0)
|
||||
self.background_combo_box = QtWidgets.QComboBox(self)
|
||||
self.background_combo_box.addItems(['', '', '', ''])
|
||||
self.background_combo_box.setObjectName('background_combo_box')
|
||||
self.layout.addWidget(self.background_combo_box, 0, 1, 1, 3)
|
||||
# color
|
||||
self.color_label = FormLabel(self)
|
||||
self.color_label.setObjectName('color_label')
|
||||
self.layout.addWidget(self.color_label, 1, 0)
|
||||
self.color_button = ColorButton(self)
|
||||
self.color_button.setObjectName('color_button')
|
||||
self.layout.addWidget(self.color_button, 1, 1)
|
||||
self.color_widgets = [self.color_label, self.color_button]
|
||||
# gradient
|
||||
self.gradient_type_label = FormLabel(self)
|
||||
self.gradient_type_label.setObjectName('gradient_type_label')
|
||||
self.layout.addWidget(self.gradient_type_label, 2, 0)
|
||||
self.gradient_combo_box = QtWidgets.QComboBox(self)
|
||||
self.gradient_combo_box.setObjectName('gradient_combo_box')
|
||||
self.gradient_combo_box.addItems(['', '', '', '', ''])
|
||||
self.layout.addWidget(self.gradient_combo_box, 2, 1, 1, 3)
|
||||
self.gradient_start_label = FormLabel(self)
|
||||
self.gradient_start_label.setObjectName('gradient_start_label')
|
||||
self.layout.addWidget(self.gradient_start_label, 3, 0)
|
||||
self.gradient_start_button = ColorButton(self)
|
||||
self.gradient_start_button.setObjectName('gradient_start_button')
|
||||
self.layout.addWidget(self.gradient_start_button, 3, 1)
|
||||
self.gradient_end_label = FormLabel(self)
|
||||
self.gradient_end_label.setObjectName('gradient_end_label')
|
||||
self.layout.addWidget(self.gradient_end_label, 3, 2)
|
||||
self.gradient_end_button = ColorButton(self)
|
||||
self.gradient_end_button.setObjectName('gradient_end_button')
|
||||
self.layout.addWidget(self.gradient_end_button, 3, 3)
|
||||
self.gradient_widgets = [self.gradient_type_label, self.gradient_combo_box, self.gradient_start_label,
|
||||
self.gradient_start_button, self.gradient_end_label, self.gradient_end_button]
|
||||
# image
|
||||
self.image_label = FormLabel(self)
|
||||
self.image_label.setObjectName('image_label')
|
||||
self.layout.addWidget(self.image_label, 4, 0)
|
||||
self.image_path_edit = PathEdit(self, dialog_caption=translate('OpenLP.ThemeWizard', 'Select Image'),
|
||||
show_revert=False)
|
||||
self.layout.addWidget(self.image_path_edit, 4, 1, 1, 3)
|
||||
self.image_color_label = FormLabel(self)
|
||||
self.image_color_label.setObjectName('image_color_label')
|
||||
self.layout.addWidget(self.image_color_label, 5, 0)
|
||||
self.image_color_button = ColorButton(self)
|
||||
self.image_color_button.color = '#000000'
|
||||
self.image_color_button.setObjectName('image_color_button')
|
||||
self.layout.addWidget(self.image_color_button, 5, 1)
|
||||
self.image_widgets = [self.image_label, self.image_path_edit, self.image_color_label, self.image_color_button]
|
||||
# video
|
||||
self.video_label = FormLabel(self)
|
||||
self.video_label.setObjectName('video_label')
|
||||
self.layout.addWidget(self.video_label, 6, 0)
|
||||
self.video_path_edit = PathEdit(self, dialog_caption=translate('OpenLP.ThemeWizard', 'Select Video'),
|
||||
show_revert=False)
|
||||
self.layout.addWidget(self.video_path_edit, 6, 1, 1, 3)
|
||||
self.video_color_label = FormLabel(self)
|
||||
self.video_color_label.setObjectName('video_color_label')
|
||||
self.layout.addWidget(self.video_color_label, 7, 0)
|
||||
self.video_color_button = ColorButton(self)
|
||||
self.video_color_button.color = '#000000'
|
||||
self.video_color_button.setObjectName('video_color_button')
|
||||
self.layout.addWidget(self.video_color_button, 7, 1)
|
||||
self.video_widgets = [self.video_label, self.video_path_edit, self.video_color_label, self.video_color_button]
|
||||
# Force everything up
|
||||
self.layout_spacer = QtWidgets.QSpacerItem(1, 1)
|
||||
self.layout.addItem(self.layout_spacer, 8, 0, 1, 4)
|
||||
# Connect slots
|
||||
self.background_combo_box.currentIndexChanged.connect(self._on_background_type_index_changed)
|
||||
# Force the first set of widgets to show
|
||||
self._on_background_type_index_changed(0)
|
||||
|
||||
def retranslate_ui(self):
|
||||
"""
|
||||
Translate the text elements of the widget
|
||||
"""
|
||||
self.background_label.setText(translate('OpenLP.ThemeWizard', 'Background type:'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Solid, translate('OpenLP.ThemeWizard', 'Solid color'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Gradient, translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Image, UiStrings().Image)
|
||||
self.background_combo_box.setItemText(BackgroundType.Transparent,
|
||||
translate('OpenLP.ThemeWizard', 'Transparent'))
|
||||
self.color_label.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||
self.gradient_start_label.setText(translate('OpenLP.ThemeWizard', 'Starting color:'))
|
||||
self.gradient_end_label.setText(translate('OpenLP.ThemeWizard', 'Ending color:'))
|
||||
self.gradient_type_label.setText(translate('OpenLP.ThemeWizard', 'Gradient:'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Horizontal,
|
||||
translate('OpenLP.ThemeWizard', 'Horizontal'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Vertical,
|
||||
translate('OpenLP.ThemeWizard', 'Vertical'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Circular,
|
||||
translate('OpenLP.ThemeWizard', 'Circular'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftTop,
|
||||
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftBottom,
|
||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||
self.image_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.image_label.setText('{text}:'.format(text=UiStrings().Image))
|
||||
self.video_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.video_label.setText('{text}:'.format(text=UiStrings().Video))
|
||||
self.image_path_edit.filters = \
|
||||
'{name};;{text} (*)'.format(name=get_images_filter(), text=UiStrings().AllFiles)
|
||||
visible_formats = '(*.{name})'.format(name='; *.'.join(VIDEO_EXT))
|
||||
actual_formats = '(*.{name})'.format(name=' *.'.join(VIDEO_EXT))
|
||||
video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
|
||||
visible=visible_formats, actual=actual_formats)
|
||||
self.video_path_edit.filters = '{video};;{ui} (*)'.format(video=video_filter, ui=UiStrings().AllFiles)
|
||||
|
||||
def _on_background_type_index_changed(self, index):
|
||||
"""
|
||||
Hide and show widgets based on index
|
||||
"""
|
||||
widget_sets = [self.color_widgets, self.gradient_widgets, self.image_widgets, [], self.video_widgets]
|
||||
for widgets in widget_sets:
|
||||
for widget in widgets:
|
||||
widget.hide()
|
||||
if index < len(widget_sets):
|
||||
for widget in widget_sets[index]:
|
||||
widget.show()
|
||||
|
||||
@property
|
||||
def background_type(self):
|
||||
return BackgroundType.to_string(self.background_combo_box.currentIndex())
|
||||
|
||||
@background_type.setter
|
||||
def background_type(self, value):
|
||||
if isinstance(value, str):
|
||||
self.background_combo_box.setCurrentIndex(BackgroundType.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.background_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('background_type must either be a string or an int')
|
||||
|
||||
@property
|
||||
def color(self):
|
||||
return self.color_button.color
|
||||
|
||||
@color.setter
|
||||
def color(self, value):
|
||||
self.color_button.color = value
|
||||
|
||||
@property
|
||||
def gradient_type(self):
|
||||
return BackgroundGradientType.to_string(self.gradient_combo_box.currentIndex())
|
||||
|
||||
@gradient_type.setter
|
||||
def gradient_type(self, value):
|
||||
if isinstance(value, str):
|
||||
self.gradient_combo_box.setCurrentIndex(BackgroundGradientType.from_string(value))
|
||||
elif isinstance(value, int):
|
||||
self.gradient_combo_box.setCurrentIndex(value)
|
||||
else:
|
||||
raise TypeError('gradient_type must either be a string or an int')
|
||||
|
||||
@property
|
||||
def gradient_start(self):
|
||||
return self.gradient_start_button.color
|
||||
|
||||
@gradient_start.setter
|
||||
def gradient_start(self, value):
|
||||
self.gradient_start_button.color = value
|
||||
|
||||
@property
|
||||
def gradient_end(self):
|
||||
return self.gradient_end_button.color
|
||||
|
||||
@gradient_end.setter
|
||||
def gradient_end(self, value):
|
||||
self.gradient_end_button.color = value
|
||||
|
||||
@property
|
||||
def image_color(self):
|
||||
return self.image_color_button.color
|
||||
|
||||
@image_color.setter
|
||||
def image_color(self, value):
|
||||
self.image_color_button.color = value
|
||||
|
||||
@property
|
||||
def image_path(self):
|
||||
return self.image_path_edit.path
|
||||
|
||||
@image_path.setter
|
||||
def image_path(self, value):
|
||||
self.image_path_edit.path = value
|
||||
|
||||
@property
|
||||
def video_color(self):
|
||||
return self.video_color_button.color
|
||||
|
||||
@video_color.setter
|
||||
def video_color(self, value):
|
||||
self.video_color_button.color = value
|
||||
|
||||
@property
|
||||
def video_path(self):
|
||||
return self.video_path_edit.path
|
||||
|
||||
@video_path.setter
|
||||
def video_path(self, value):
|
||||
self.video_path_edit.path = value
|
345
openlp/core/pages/fontselect.py
Normal file
345
openlp/core/pages/fontselect.py
Normal file
@ -0,0 +1,345 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.pages.fontselect` module contains the font selection page used in the theme wizard
|
||||
"""
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.pages import GridLayoutPage
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
from openlp.core.widgets.labels import FormLabel
|
||||
|
||||
|
||||
class FontSelectPage(GridLayoutPage):
|
||||
"""
|
||||
A font selection widget
|
||||
"""
|
||||
Outline = 'outline'
|
||||
Shadow = 'shadow'
|
||||
LineSpacing = 'line_spacing'
|
||||
|
||||
font_name_changed = QtCore.pyqtSignal(str)
|
||||
font_size_changed = QtCore.pyqtSignal(int)
|
||||
font_color_changed = QtCore.pyqtSignal(str)
|
||||
is_bold_changed = QtCore.pyqtSignal(bool)
|
||||
is_italic_changed = QtCore.pyqtSignal(bool)
|
||||
line_spacing_changed = QtCore.pyqtSignal(int)
|
||||
is_outline_enabled_changed = QtCore.pyqtSignal(bool)
|
||||
outline_color_changed = QtCore.pyqtSignal(str)
|
||||
outline_size_changed = QtCore.pyqtSignal(int)
|
||||
is_shadow_enabled_changed = QtCore.pyqtSignal(bool)
|
||||
shadow_color_changed = QtCore.pyqtSignal(str)
|
||||
shadow_size_changed = QtCore.pyqtSignal(int)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.feature_widgets = {
|
||||
FontSelectPage.Outline: [self.outline_groupbox],
|
||||
FontSelectPage.Shadow: [self.shadow_groupbox],
|
||||
FontSelectPage.LineSpacing: [self.line_spacing_label, self.line_spacing_spinbox]
|
||||
}
|
||||
|
||||
def setup_ui(self):
|
||||
# Font name
|
||||
self.font_name_label = FormLabel(self)
|
||||
self.font_name_label.setObjectName('font_name_label')
|
||||
self.layout.addWidget(self.font_name_label, 0, 0)
|
||||
self.font_name_combobox = QtWidgets.QFontComboBox(self)
|
||||
self.font_name_combobox.setObjectName('font_name_combobox')
|
||||
self.layout.addWidget(self.font_name_combobox, 0, 1, 1, 3)
|
||||
# Font color
|
||||
self.font_color_label = FormLabel(self)
|
||||
self.font_color_label.setObjectName('font_color_label')
|
||||
self.layout.addWidget(self.font_color_label, 1, 0)
|
||||
self.font_color_button = ColorButton(self)
|
||||
self.font_color_button.setObjectName('font_color_button')
|
||||
self.layout.addWidget(self.font_color_button, 1, 1)
|
||||
# Font style
|
||||
self.font_style_label = FormLabel(self)
|
||||
self.font_style_label.setObjectName('font_style_label')
|
||||
self.layout.addWidget(self.font_style_label, 1, 2)
|
||||
self.style_layout = QtWidgets.QHBoxLayout()
|
||||
self.style_bold_button = QtWidgets.QToolButton(self)
|
||||
self.style_bold_button.setCheckable(True)
|
||||
self.style_bold_button.setIcon(UiIcons().bold)
|
||||
self.style_bold_button.setShortcut(QtGui.QKeySequence(QtGui.QKeySequence.Bold))
|
||||
self.style_bold_button.setObjectName('style_bold_button')
|
||||
self.style_layout.addWidget(self.style_bold_button)
|
||||
self.style_italic_button = QtWidgets.QToolButton(self)
|
||||
self.style_italic_button.setCheckable(True)
|
||||
self.style_italic_button.setIcon(UiIcons().italic)
|
||||
self.style_italic_button.setShortcut(QtGui.QKeySequence(QtGui.QKeySequence.Italic))
|
||||
self.style_italic_button.setObjectName('style_italic_button')
|
||||
self.style_layout.addWidget(self.style_italic_button)
|
||||
self.style_layout.addStretch(1)
|
||||
self.layout.addLayout(self.style_layout, 1, 3)
|
||||
# Font size
|
||||
self.font_size_label = FormLabel(self)
|
||||
self.font_size_label.setObjectName('font_size_label')
|
||||
self.layout.addWidget(self.font_size_label, 2, 0)
|
||||
self.font_size_spinbox = QtWidgets.QSpinBox(self)
|
||||
self.font_size_spinbox.setMaximum(999)
|
||||
self.font_size_spinbox.setValue(16)
|
||||
self.font_size_spinbox.setObjectName('font_size_spinbox')
|
||||
self.layout.addWidget(self.font_size_spinbox, 2, 1)
|
||||
# Line spacing
|
||||
self.line_spacing_label = FormLabel(self)
|
||||
self.line_spacing_label.setObjectName('line_spacing_label')
|
||||
self.layout.addWidget(self.line_spacing_label, 2, 2)
|
||||
self.line_spacing_spinbox = QtWidgets.QSpinBox(self)
|
||||
self.line_spacing_spinbox.setMinimum(-250)
|
||||
self.line_spacing_spinbox.setMaximum(250)
|
||||
self.line_spacing_spinbox.setObjectName('line_spacing_spinbox')
|
||||
self.layout.addWidget(self.line_spacing_spinbox, 2, 3)
|
||||
# Outline
|
||||
self.outline_groupbox = QtWidgets.QGroupBox(self)
|
||||
self.outline_groupbox.setCheckable(True)
|
||||
self.outline_groupbox.setChecked(False)
|
||||
self.outline_groupbox.setObjectName('outline_groupbox')
|
||||
self.outline_layout = QtWidgets.QGridLayout(self.outline_groupbox)
|
||||
self.layout.addWidget(self.outline_groupbox, 3, 0, 1, 2)
|
||||
# Outline colour
|
||||
self.outline_color_label = FormLabel(self.outline_groupbox)
|
||||
self.outline_color_label.setObjectName('outline_color_label')
|
||||
self.outline_layout.addWidget(self.outline_color_label, 0, 0)
|
||||
self.outline_color_button = ColorButton(self.outline_groupbox)
|
||||
self.outline_color_button.setObjectName('outline_color_button')
|
||||
self.outline_layout.addWidget(self.outline_color_button, 0, 1)
|
||||
# Outline size
|
||||
self.outline_size_label = FormLabel(self.outline_groupbox)
|
||||
self.outline_size_label.setObjectName('outline_size_label')
|
||||
self.outline_layout.addWidget(self.outline_size_label, 1, 0)
|
||||
self.outline_size_spinbox = QtWidgets.QSpinBox(self.outline_groupbox)
|
||||
self.outline_size_spinbox.setMaximum(9999)
|
||||
self.outline_size_spinbox.setObjectName('outline_size_spinbox')
|
||||
self.outline_layout.addWidget(self.outline_size_spinbox, 1, 1)
|
||||
# Shadow
|
||||
self.shadow_groupbox = QtWidgets.QGroupBox(self)
|
||||
self.shadow_groupbox.setCheckable(True)
|
||||
self.shadow_groupbox.setChecked(False)
|
||||
self.shadow_groupbox.setObjectName('shadow_groupbox')
|
||||
self.shadow_layout = QtWidgets.QGridLayout(self.shadow_groupbox)
|
||||
self.layout.addWidget(self.shadow_groupbox, 3, 2, 1, 2)
|
||||
# Shadow color
|
||||
self.shadow_color_label = FormLabel(self.shadow_groupbox)
|
||||
self.shadow_color_label.setObjectName('shadow_color_label')
|
||||
self.shadow_layout.addWidget(self.shadow_color_label, 0, 0)
|
||||
self.shadow_color_button = ColorButton(self.shadow_groupbox)
|
||||
self.shadow_color_button.setObjectName('shadow_color_button')
|
||||
self.shadow_layout.addWidget(self.shadow_color_button, 0, 1)
|
||||
# Shadow size
|
||||
self.shadow_size_label = FormLabel(self.shadow_groupbox)
|
||||
self.shadow_size_label.setObjectName('shadow_size_label')
|
||||
self.shadow_layout.addWidget(self.shadow_size_label, 1, 0)
|
||||
self.shadow_size_spinbox = QtWidgets.QSpinBox(self.shadow_groupbox)
|
||||
self.shadow_size_spinbox.setMaximum(9999)
|
||||
self.shadow_size_spinbox.setObjectName('shadow_size_spinbox')
|
||||
self.shadow_layout.addWidget(self.shadow_size_spinbox, 1, 1)
|
||||
# Connect all the signals
|
||||
self.font_name_combobox.activated.connect(self._on_font_name_changed)
|
||||
self.font_color_button.colorChanged.connect(self._on_font_color_changed)
|
||||
self.style_bold_button.toggled.connect(self._on_style_bold_toggled)
|
||||
self.style_italic_button.toggled.connect(self._on_style_italic_toggled)
|
||||
self.font_size_spinbox.valueChanged.connect(self._on_font_size_changed)
|
||||
self.line_spacing_spinbox.valueChanged.connect(self._on_line_spacing_changed)
|
||||
self.outline_groupbox.toggled.connect(self._on_outline_toggled)
|
||||
self.outline_color_button.colorChanged.connect(self._on_outline_color_changed)
|
||||
self.outline_size_spinbox.valueChanged.connect(self._on_outline_size_changed)
|
||||
self.shadow_groupbox.toggled.connect(self._on_shadow_toggled)
|
||||
self.shadow_color_button.colorChanged.connect(self._on_shadow_color_changed)
|
||||
self.shadow_size_spinbox.valueChanged.connect(self._on_shadow_size_changed)
|
||||
|
||||
def retranslate_ui(self):
|
||||
self.font_name_label.setText(translate('OpenLP.FontSelectWidget', 'Font:'))
|
||||
self.font_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.font_style_label.setText(translate('OpenLP.FontSelectWidget', 'Style:'))
|
||||
self.style_bold_button.setToolTip('{name} ({shortcut})'.format(
|
||||
name=translate('OpenLP.FontSelectWidget', 'Bold'),
|
||||
shortcut=QtGui.QKeySequence(QtGui.QKeySequence.Bold).toString()
|
||||
))
|
||||
self.style_italic_button.setToolTip('{name} ({shortcut})'.format(
|
||||
name=translate('OpenLP.FontSelectWidget', 'Italic'),
|
||||
shortcut=QtGui.QKeySequence(QtGui.QKeySequence.Italic).toString()
|
||||
))
|
||||
self.font_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
self.font_size_spinbox.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
|
||||
self.line_spacing_label.setText(translate('OpenLP.FontSelectWidget', 'Line Spacing:'))
|
||||
self.outline_groupbox.setTitle(translate('OpenLP.FontSelectWidget', 'Outline'))
|
||||
self.outline_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.outline_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
self.shadow_groupbox.setTitle(translate('OpenLP.FontSelectWidget', 'Shadow'))
|
||||
self.shadow_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.shadow_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
|
||||
def _on_font_name_changed(self, name):
|
||||
if isinstance(name, str):
|
||||
self.font_name_changed.emit(name)
|
||||
|
||||
def _on_font_color_changed(self, color):
|
||||
self.font_color_changed.emit(color)
|
||||
|
||||
def _on_style_bold_toggled(self, is_bold):
|
||||
self.is_bold_changed.emit(is_bold)
|
||||
|
||||
def _on_style_italic_toggled(self, is_italic):
|
||||
self.is_italic_changed.emit(is_italic)
|
||||
|
||||
def _on_font_size_changed(self, size):
|
||||
self.font_size_changed.emit(size)
|
||||
|
||||
def _on_line_spacing_changed(self, spacing):
|
||||
self.line_spacing_changed.emit(spacing)
|
||||
|
||||
def _on_outline_toggled(self, is_enabled):
|
||||
self.is_outline_enabled_changed.emit(is_enabled)
|
||||
|
||||
def _on_outline_color_changed(self, color):
|
||||
self.outline_color_changed.emit(color)
|
||||
|
||||
def _on_outline_size_changed(self, size):
|
||||
self.outline_size_changed.emit(size)
|
||||
|
||||
def _on_shadow_toggled(self, is_enabled):
|
||||
self.is_shadow_enabled_changed.emit(is_enabled)
|
||||
|
||||
def _on_shadow_color_changed(self, color):
|
||||
self.shadow_color_changed.emit(color)
|
||||
|
||||
def _on_shadow_size_changed(self, size):
|
||||
self.shadow_size_changed.emit(size)
|
||||
|
||||
def enable_features(self, *features):
|
||||
"""
|
||||
Enable a feature
|
||||
"""
|
||||
for feature_name in features:
|
||||
if feature_name not in self.feature_widgets.keys():
|
||||
raise KeyError('No such feature: {feature_name}'.format(feature_name=feature_name))
|
||||
for widget in self.feature_widgets[feature_name]:
|
||||
widget.show()
|
||||
|
||||
def disable_features(self, *features):
|
||||
"""
|
||||
Disable a feature
|
||||
"""
|
||||
for feature_name in features:
|
||||
if feature_name not in self.feature_widgets.keys():
|
||||
raise KeyError('No such feature: {feature_name}'.format(feature_name=feature_name))
|
||||
for widget in self.feature_widgets[feature_name]:
|
||||
widget.hide()
|
||||
|
||||
@property
|
||||
def font_name(self):
|
||||
return self.font_name_combobox.currentFont().family()
|
||||
|
||||
@font_name.setter
|
||||
def font_name(self, font):
|
||||
self.font_name_combobox.setCurrentFont(QtGui.QFont(font))
|
||||
|
||||
@property
|
||||
def font_color(self):
|
||||
return self.font_color_button.color
|
||||
|
||||
@font_color.setter
|
||||
def font_color(self, color):
|
||||
self.font_color_button.color = color
|
||||
|
||||
@property
|
||||
def is_bold(self):
|
||||
return self.style_bold_button.isChecked()
|
||||
|
||||
@is_bold.setter
|
||||
def is_bold(self, is_bold):
|
||||
self.style_bold_button.setChecked(is_bold)
|
||||
|
||||
@property
|
||||
def is_italic(self):
|
||||
return self.style_italic_button.isChecked()
|
||||
|
||||
@is_italic.setter
|
||||
def is_italic(self, is_italic):
|
||||
self.style_italic_button.setChecked(is_italic)
|
||||
|
||||
@property
|
||||
def font_size(self):
|
||||
return self.font_size_spinbox.value()
|
||||
|
||||
@font_size.setter
|
||||
def font_size(self, size):
|
||||
self.font_size_spinbox.setValue(size)
|
||||
|
||||
@property
|
||||
def line_spacing(self):
|
||||
return self.line_spacing_spinbox.value()
|
||||
|
||||
@line_spacing.setter
|
||||
def line_spacing(self, line_spacing):
|
||||
self.line_spacing_spinbox.setValue(line_spacing)
|
||||
|
||||
@property
|
||||
def is_outline_enabled(self):
|
||||
return self.outline_groupbox.isChecked()
|
||||
|
||||
@is_outline_enabled.setter
|
||||
def is_outline_enabled(self, is_enabled):
|
||||
self.outline_groupbox.setChecked(is_enabled)
|
||||
|
||||
@property
|
||||
def outline_color(self):
|
||||
return self.outline_color_button.color
|
||||
|
||||
@outline_color.setter
|
||||
def outline_color(self, color):
|
||||
self.outline_color_button.color = color
|
||||
|
||||
@property
|
||||
def outline_size(self):
|
||||
return self.outline_size_spinbox.value()
|
||||
|
||||
@outline_size.setter
|
||||
def outline_size(self, size):
|
||||
self.outline_size_spinbox.setValue(size)
|
||||
|
||||
@property
|
||||
def is_shadow_enabled(self):
|
||||
return self.shadow_groupbox.isChecked()
|
||||
|
||||
@is_shadow_enabled.setter
|
||||
def is_shadow_enabled(self, is_enabled):
|
||||
self.shadow_groupbox.setChecked(is_enabled)
|
||||
|
||||
@property
|
||||
def shadow_color(self):
|
||||
return self.shadow_color_button.color
|
||||
|
||||
@shadow_color.setter
|
||||
def shadow_color(self, color):
|
||||
self.shadow_color_button.color = color
|
||||
|
||||
@property
|
||||
def shadow_size(self):
|
||||
return self.shadow_size_spinbox.value()
|
||||
|
||||
@shadow_size.setter
|
||||
def shadow_size(self, size):
|
||||
self.shadow_size_spinbox.setValue(size)
|
@ -25,13 +25,12 @@ import logging
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import get_images_filter, is_not_image_file
|
||||
from openlp.core.common import is_not_image_file
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib.theme import BackgroundGradientType, BackgroundType
|
||||
from openlp.core.lib.theme import BackgroundType
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.media import VIDEO_EXT
|
||||
from openlp.core.ui.themelayoutform import ThemeLayoutForm
|
||||
from openlp.core.ui.themewizard import Ui_ThemeWizard
|
||||
|
||||
@ -60,42 +59,21 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
Set up the class. This method is mocked out by the tests.
|
||||
"""
|
||||
self.setup_ui(self)
|
||||
self.registerFields()
|
||||
self.update_theme_allowed = True
|
||||
self.can_update_theme = True
|
||||
self.temp_background_filename = None
|
||||
self.theme_layout_form = ThemeLayoutForm(self)
|
||||
self.background_combo_box.currentIndexChanged.connect(self.on_background_combo_box_current_index_changed)
|
||||
self.gradient_combo_box.currentIndexChanged.connect(self.on_gradient_combo_box_current_index_changed)
|
||||
self.color_button.colorChanged.connect(self.on_color_changed)
|
||||
self.image_color_button.colorChanged.connect(self.on_image_color_changed)
|
||||
self.video_color_button.colorChanged.connect(self.on_video_color_changed)
|
||||
self.gradient_start_button.colorChanged.connect(self.on_gradient_start_color_changed)
|
||||
self.gradient_end_button.colorChanged.connect(self.on_gradient_end_color_changed)
|
||||
self.image_path_edit.filters = \
|
||||
'{name};;{text} (*)'.format(name=get_images_filter(), text=UiStrings().AllFiles)
|
||||
self.image_path_edit.pathChanged.connect(self.on_image_path_edit_path_changed)
|
||||
visible_formats = '(*.{name})'.format(name='; *.'.join(VIDEO_EXT))
|
||||
actual_formats = '(*.{name})'.format(name=' *.'.join(VIDEO_EXT))
|
||||
video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
|
||||
visible=visible_formats, actual=actual_formats)
|
||||
self.video_path_edit.filters = '{video};;{ui} (*)'.format(video=video_filter, ui=UiStrings().AllFiles)
|
||||
self.video_path_edit.pathChanged.connect(self.on_video_path_edit_path_changed)
|
||||
self.footer_color_button.colorChanged.connect(self.on_footer_color_changed)
|
||||
self.customButtonClicked.connect(self.on_custom_1_button_clicked)
|
||||
self.main_position_check_box.stateChanged.connect(self.on_main_position_check_box_state_changed)
|
||||
self.footer_position_check_box.stateChanged.connect(self.on_footer_position_check_box_state_changed)
|
||||
self.currentIdChanged.connect(self.on_current_id_changed)
|
||||
Registry().register_function('theme_line_count', self.update_lines_text)
|
||||
self.main_font.font_name_changed.connect(self.calculate_lines)
|
||||
self.main_font.font_size_changed.connect(self.calculate_lines)
|
||||
self.main_font.line_spacing_changed.connect(self.calculate_lines)
|
||||
self.main_font.is_outline_enabled_changed.connect(self.on_outline_toggled)
|
||||
self.main_font.outline_size_changed.connect(self.calculate_lines)
|
||||
self.main_font.is_shadow_enabled_changed.connect(self.on_shadow_toggled)
|
||||
self.main_font.shadow_size_changed.connect(self.calculate_lines)
|
||||
self.footer_font_combo_box.activated.connect(self.update_theme)
|
||||
self.footer_size_spin_box.valueChanged.connect(self.update_theme)
|
||||
self.transitions_check_box.stateChanged.connect(self.on_transitions_check_box_state_changed)
|
||||
self.main_area_page.font_name_changed.connect(self.calculate_lines)
|
||||
self.main_area_page.font_size_changed.connect(self.calculate_lines)
|
||||
self.main_area_page.line_spacing_changed.connect(self.calculate_lines)
|
||||
self.main_area_page.is_outline_enabled_changed.connect(self.on_outline_toggled)
|
||||
self.main_area_page.outline_size_changed.connect(self.calculate_lines)
|
||||
self.main_area_page.is_shadow_enabled_changed.connect(self.on_shadow_toggled)
|
||||
self.main_area_page.shadow_size_changed.connect(self.calculate_lines)
|
||||
self.footer_area_page.font_name_changed.connect(self.update_theme)
|
||||
self.footer_area_page.font_size_changed.connect(self.update_theme)
|
||||
|
||||
def set_defaults(self):
|
||||
"""
|
||||
@ -109,33 +87,6 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
self.set_position_page_values()
|
||||
self.set_preview_page_values()
|
||||
|
||||
def registerFields(self):
|
||||
"""
|
||||
Map field names to screen names,
|
||||
"""
|
||||
self.background_page.registerField('background_type', self.background_combo_box)
|
||||
self.background_page.registerField('color', self.color_button)
|
||||
self.background_page.registerField('gradient_start', self.gradient_start_button)
|
||||
self.background_page.registerField('gradient_end', self.gradient_end_button)
|
||||
self.background_page.registerField('background_image', self.image_path_edit,
|
||||
'path', self.image_path_edit.pathChanged)
|
||||
self.background_page.registerField('gradient', self.gradient_combo_box)
|
||||
self.main_area_page.registerField('footer_size_spin_box', self.footer_size_spin_box)
|
||||
self.area_position_page.registerField('main_position_x', self.main_x_spin_box)
|
||||
self.area_position_page.registerField('main_position_y', self.main_y_spin_box)
|
||||
self.area_position_page.registerField('main_position_width', self.main_width_spin_box)
|
||||
self.area_position_page.registerField('main_position_height', self.main_height_spin_box)
|
||||
self.area_position_page.registerField('footer_position_x', self.footer_x_spin_box)
|
||||
self.area_position_page.registerField('footer_position_y', self.footer_y_spin_box)
|
||||
self.area_position_page.registerField('footer_position_width', self.footer_width_spin_box)
|
||||
self.area_position_page.registerField('footer_position_height', self.footer_height_spin_box)
|
||||
self.background_page.registerField('horizontal', self.horizontal_combo_box)
|
||||
self.background_page.registerField('vertical', self.vertical_combo_box)
|
||||
self.background_page.registerField('slide_transition', self.transitions_check_box)
|
||||
self.background_page.registerField('slide_transition_type', self.transition_combo_box)
|
||||
self.background_page.registerField('slide_transition_speed', self.transition_speed_combo_box)
|
||||
self.background_page.registerField('name', self.theme_name_edit)
|
||||
|
||||
def calculate_lines(self, *args):
|
||||
"""
|
||||
Calculate the number of lines on a page by rendering text
|
||||
@ -175,7 +126,8 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
background_image = BackgroundType.to_string(BackgroundType.Image)
|
||||
if self.page(self.currentId()) == self.background_page and \
|
||||
self.theme.background_type == background_image and is_not_image_file(self.theme.background_filename):
|
||||
self.background_page.background_type == background_image and \
|
||||
is_not_image_file(self.background_page.image_path):
|
||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ThemeWizard', 'Background Image Empty'),
|
||||
translate('OpenLP.ThemeWizard', 'You have not selected a '
|
||||
'background image. Please select one before continuing.'))
|
||||
@ -229,7 +181,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Change state as Outline check box changed
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
if self.can_update_theme:
|
||||
self.theme.font_main_outline = is_enabled
|
||||
self.calculate_lines()
|
||||
|
||||
@ -237,45 +189,19 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Change state as Shadow check box changed
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
if self.can_update_theme:
|
||||
self.theme.font_main_shadow = is_enabled
|
||||
self.calculate_lines()
|
||||
|
||||
def on_main_position_check_box_state_changed(self, value):
|
||||
"""
|
||||
Change state as Main Area _position check box changed
|
||||
NOTE the font_main_override is the inverse of the check box value
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.font_main_override = (value != QtCore.Qt.Checked)
|
||||
|
||||
def on_footer_position_check_box_state_changed(self, value):
|
||||
"""
|
||||
Change state as Footer Area _position check box changed
|
||||
NOTE the font_footer_override is the inverse of the check box value
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.font_footer_override = (value != QtCore.Qt.Checked)
|
||||
|
||||
def on_transitions_check_box_state_changed(self, state):
|
||||
"""
|
||||
Change state as Transitions check box is changed
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.display_slide_transition = state == QtCore.Qt.Checked
|
||||
self.transition_combo_box.setEnabled(self.theme.display_slide_transition)
|
||||
self.transition_speed_combo_box.setEnabled(self.theme.display_slide_transition)
|
||||
self.calculate_lines()
|
||||
|
||||
def exec(self, edit=False):
|
||||
"""
|
||||
Run the wizard.
|
||||
"""
|
||||
log.debug('Editing theme {name}'.format(name=self.theme.theme_name))
|
||||
self.temp_background_filename = self.theme.background_source
|
||||
self.update_theme_allowed = False
|
||||
self.can_update_theme = False
|
||||
self.set_defaults()
|
||||
self.update_theme_allowed = True
|
||||
self.can_update_theme = True
|
||||
self.theme_name_label.setVisible(not edit)
|
||||
self.theme_name_edit.setVisible(not edit)
|
||||
self.edit_mode = edit
|
||||
@ -308,228 +234,150 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
Handle the display and state of the Background page.
|
||||
"""
|
||||
self.background_page.background_type = self.theme.background_type
|
||||
if self.theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
|
||||
self.color_button.color = self.theme.background_color
|
||||
self.setField('background_type', 0)
|
||||
self.background_page.color = self.theme.background_color
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Gradient):
|
||||
self.gradient_start_button.color = self.theme.background_start_color
|
||||
self.gradient_end_button.color = self.theme.background_end_color
|
||||
self.setField('background_type', 1)
|
||||
self.background_page.gradient_start = self.theme.background_start_color
|
||||
self.background_page.gradient_end = self.theme.background_end_color
|
||||
self.background_page.gradient_type = self.theme.background_direction
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):
|
||||
self.image_color_button.color = self.theme.background_border_color
|
||||
self.image_path_edit.path = self.theme.background_source
|
||||
self.setField('background_type', 2)
|
||||
self.background_page.image_color = self.theme.background_border_color
|
||||
if self.theme.background_source and self.theme.background_source.exists():
|
||||
self.background_page.image_path = self.theme.background_source
|
||||
else:
|
||||
self.background_page.image_path = self.theme.background_filename
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
|
||||
self.video_color_button.color = self.theme.background_border_color
|
||||
self.video_path_edit.path = self.theme.background_source
|
||||
self.setField('background_type', 4)
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Stream):
|
||||
self.setField('background_type', 5)
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
|
||||
self.setField('background_type', 3)
|
||||
if self.theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
|
||||
self.setField('gradient', 0)
|
||||
elif self.theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Vertical):
|
||||
self.setField('gradient', 1)
|
||||
elif self.theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Circular):
|
||||
self.setField('gradient', 2)
|
||||
elif self.theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftTop):
|
||||
self.setField('gradient', 3)
|
||||
else:
|
||||
self.setField('gradient', 4)
|
||||
self.background_page.video_color = self.theme.background_border_color
|
||||
if self.theme.background_source and self.theme.background_source.exists():
|
||||
self.background_page.video_path = self.theme.background_source
|
||||
else:
|
||||
self.background_page.video_path = self.theme.background_filename
|
||||
|
||||
def set_main_area_page_values(self):
|
||||
"""
|
||||
Handle the display and state of the Main Area page.
|
||||
"""
|
||||
self.main_font.font_name = self.theme.font_main_name
|
||||
self.main_font.font_color = self.theme.font_main_color
|
||||
self.main_font.font_size = self.theme.font_main_size
|
||||
self.main_font.line_spacing = self.theme.font_main_line_adjustment
|
||||
self.main_font.is_outline_enabled = self.theme.font_main_outline
|
||||
self.main_font.outline_color = self.theme.font_main_outline_color
|
||||
self.main_font.outline_size = self.theme.font_main_outline_size
|
||||
self.main_font.is_shadow_enabled = self.theme.font_main_shadow
|
||||
self.main_font.shadow_color = self.theme.font_main_shadow_color
|
||||
self.main_font.shadow_size = self.theme.font_main_shadow_size
|
||||
self.main_font.is_bold = self.theme.font_main_bold
|
||||
self.main_font.is_italic = self.theme.font_main_italics
|
||||
self.main_area_page.font_name = self.theme.font_main_name
|
||||
self.main_area_page.font_color = self.theme.font_main_color
|
||||
self.main_area_page.font_size = self.theme.font_main_size
|
||||
self.main_area_page.line_spacing = self.theme.font_main_line_adjustment
|
||||
self.main_area_page.is_outline_enabled = self.theme.font_main_outline
|
||||
self.main_area_page.outline_color = self.theme.font_main_outline_color
|
||||
self.main_area_page.outline_size = self.theme.font_main_outline_size
|
||||
self.main_area_page.is_shadow_enabled = self.theme.font_main_shadow
|
||||
self.main_area_page.shadow_color = self.theme.font_main_shadow_color
|
||||
self.main_area_page.shadow_size = self.theme.font_main_shadow_size
|
||||
self.main_area_page.is_bold = self.theme.font_main_bold
|
||||
self.main_area_page.is_italic = self.theme.font_main_italics
|
||||
|
||||
def set_footer_area_page_values(self):
|
||||
"""
|
||||
Handle the display and state of the Footer Area page.
|
||||
"""
|
||||
self.footer_font_combo_box.setCurrentFont(QtGui.QFont(self.theme.font_footer_name))
|
||||
self.footer_color_button.color = self.theme.font_footer_color
|
||||
self.setField('footer_size_spin_box', self.theme.font_footer_size)
|
||||
self.footer_area_page.font_name = self.theme.font_footer_name
|
||||
self.footer_area_page.font_color = self.theme.font_footer_color
|
||||
|
||||
def set_position_page_values(self):
|
||||
"""
|
||||
Handle the display and state of the _position page.
|
||||
"""
|
||||
# Main Area
|
||||
self.main_position_check_box.setChecked(not self.theme.font_main_override)
|
||||
self.setField('main_position_x', self.theme.font_main_x)
|
||||
self.setField('main_position_y', self.theme.font_main_y)
|
||||
self.setField('main_position_height', self.theme.font_main_height)
|
||||
self.setField('main_position_width', self.theme.font_main_width)
|
||||
self.area_position_page.use_main_default_location = not self.theme.font_main_override
|
||||
self.area_position_page.main_x = self.theme.font_main_x
|
||||
self.area_position_page.main_y = self.theme.font_main_y
|
||||
self.area_position_page.main_height = self.theme.font_main_height
|
||||
self.area_position_page.main_width = self.theme.font_main_width
|
||||
# Footer
|
||||
self.footer_position_check_box.setChecked(not self.theme.font_footer_override)
|
||||
self.setField('footer_position_x', self.theme.font_footer_x)
|
||||
self.setField('footer_position_y', self.theme.font_footer_y)
|
||||
self.setField('footer_position_height', self.theme.font_footer_height)
|
||||
self.setField('footer_position_width', self.theme.font_footer_width)
|
||||
self.area_position_page.use_footer_default_location = not self.theme.font_footer_override
|
||||
self.area_position_page.footer_x = self.theme.font_footer_x
|
||||
self.area_position_page.footer_y = self.theme.font_footer_y
|
||||
self.area_position_page.footer_height = self.theme.font_footer_height
|
||||
self.area_position_page.footer_width = self.theme.font_footer_width
|
||||
|
||||
def set_alignment_page_values(self):
|
||||
"""
|
||||
Handle the display and state of the Alignments page.
|
||||
"""
|
||||
self.setField('horizontal', self.theme.display_horizontal_align)
|
||||
self.setField('vertical', self.theme.display_vertical_align)
|
||||
self.setField('slide_transition', self.theme.display_slide_transition)
|
||||
self.setField('slide_transition_type', self.theme.display_slide_transition_type)
|
||||
self.setField('slide_transition_speed', self.theme.display_slide_transition_speed)
|
||||
self.alignment_page.horizontal_align = self.theme.display_horizontal_align
|
||||
self.alignment_page.vertical_align = self.theme.display_vertical_align
|
||||
self.alignment_page.is_transition_enabled = self.theme.display_slide_transition
|
||||
self.alignment_page.transition_type = self.theme.display_slide_transition_type
|
||||
self.alignment_page.transition_speed = self.theme.display_slide_transition_speed
|
||||
|
||||
def set_preview_page_values(self):
|
||||
"""
|
||||
Handle the display and state of the Preview page.
|
||||
"""
|
||||
self.setField('name', self.theme.theme_name)
|
||||
self.theme_name_edit.setText(self.theme.theme_name)
|
||||
self.preview_box.set_theme(self.theme)
|
||||
|
||||
def on_background_combo_box_current_index_changed(self, index):
|
||||
"""
|
||||
Background style Combo box has changed.
|
||||
"""
|
||||
# do not allow updates when screen is building for the first time.
|
||||
if self.update_theme_allowed:
|
||||
self.theme.background_type = BackgroundType.to_string(index)
|
||||
if self.theme.background_type != BackgroundType.to_string(BackgroundType.Image) and \
|
||||
self.theme.background_type != BackgroundType.to_string(BackgroundType.Video) and \
|
||||
self.temp_background_filename is None:
|
||||
self.temp_background_filename = self.theme.background_filename
|
||||
self.theme.background_filename = None
|
||||
if (self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or
|
||||
self.theme.background_type != BackgroundType.to_string(BackgroundType.Video)) and \
|
||||
self.temp_background_filename is not None:
|
||||
self.theme.background_filename = self.temp_background_filename
|
||||
self.temp_background_filename = None
|
||||
self.set_background_page_values()
|
||||
|
||||
def on_gradient_combo_box_current_index_changed(self, index):
|
||||
"""
|
||||
Background gradient Combo box has changed.
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.background_direction = BackgroundGradientType.to_string(index)
|
||||
self.set_background_page_values()
|
||||
|
||||
def on_color_changed(self, color):
|
||||
"""
|
||||
Background / Gradient 1 _color button pushed.
|
||||
"""
|
||||
self.theme.background_color = color
|
||||
|
||||
def on_image_color_changed(self, color):
|
||||
"""
|
||||
Background / Gradient 1 _color button pushed.
|
||||
"""
|
||||
self.theme.background_border_color = color
|
||||
|
||||
def on_video_color_changed(self, color):
|
||||
"""
|
||||
Background / Gradient 1 _color button pushed.
|
||||
"""
|
||||
self.theme.background_border_color = color
|
||||
|
||||
def on_gradient_start_color_changed(self, color):
|
||||
"""
|
||||
Gradient 2 _color button pushed.
|
||||
"""
|
||||
self.theme.background_start_color = color
|
||||
|
||||
def on_gradient_end_color_changed(self, color):
|
||||
"""
|
||||
Gradient 2 _color button pushed.
|
||||
"""
|
||||
self.theme.background_end_color = color
|
||||
|
||||
def on_image_path_edit_path_changed(self, new_path):
|
||||
"""
|
||||
Handle the `pathEditChanged` signal from image_path_edit
|
||||
|
||||
:param pathlib.Path new_path: Path to the new image
|
||||
:rtype: None
|
||||
"""
|
||||
self.theme.background_source = new_path
|
||||
self.theme.background_filename = new_path
|
||||
self.set_background_page_values()
|
||||
|
||||
def on_video_path_edit_path_changed(self, new_path):
|
||||
"""
|
||||
Handle the `pathEditChanged` signal from video_path_edit
|
||||
|
||||
:param pathlib.Path new_path: Path to the new video
|
||||
:rtype: None
|
||||
"""
|
||||
self.theme.background_source = new_path
|
||||
self.theme.background_filename = new_path
|
||||
self.set_background_page_values()
|
||||
|
||||
def on_footer_color_changed(self, color):
|
||||
"""
|
||||
Set the footer colour value
|
||||
"""
|
||||
self.theme.font_footer_color = color
|
||||
|
||||
def update_theme(self):
|
||||
"""
|
||||
Update the theme object from the UI for fields not already updated
|
||||
when the are changed.
|
||||
"""
|
||||
if not self.update_theme_allowed:
|
||||
if not self.can_update_theme:
|
||||
return
|
||||
log.debug('update_theme')
|
||||
# background page
|
||||
self.theme.background_type = self.background_page.background_type
|
||||
if self.theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
|
||||
self.theme.background_color = self.background_page.color
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Gradient):
|
||||
self.theme.background_direction = self.background_page.gradient_type
|
||||
self.theme.background_start_color = self.background_page.gradient_start
|
||||
self.theme.background_end_color = self.background_page.gradient_end
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):
|
||||
self.theme.background_border_color = self.background_page.image_color
|
||||
self.theme.background_source = self.background_page.image_path
|
||||
self.theme.background_filename = self.background_page.image_path
|
||||
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
|
||||
self.theme.background_border_color = self.background_page.video_color
|
||||
self.theme.background_source = self.background_page.video_path
|
||||
self.theme.background_filename = self.background_page.video_path
|
||||
# main page
|
||||
self.theme.font_main_name = self.main_font.font_name
|
||||
self.theme.font_main_size = self.main_font.font_size
|
||||
self.theme.font_main_line_adjustment = self.main_font.line_spacing
|
||||
self.theme.font_main_outline_size = self.main_font.outline_size
|
||||
self.theme.font_main_shadow_size = self.main_font.shadow_size
|
||||
self.theme.font_main_bold = self.main_font.is_bold
|
||||
self.theme.font_main_italics = self.main_font.is_italic
|
||||
self.theme.font_main_name = self.main_area_page.font_name
|
||||
self.theme.font_main_size = self.main_area_page.font_size
|
||||
self.theme.font_main_line_adjustment = self.main_area_page.line_spacing
|
||||
self.theme.font_main_outline_size = self.main_area_page.outline_size
|
||||
self.theme.font_main_shadow_size = self.main_area_page.shadow_size
|
||||
self.theme.font_main_bold = self.main_area_page.is_bold
|
||||
self.theme.font_main_italics = self.main_area_page.is_italic
|
||||
# footer page
|
||||
self.theme.font_footer_name = self.footer_font_combo_box.currentFont().family()
|
||||
self.theme.font_footer_size = self.field('footer_size_spin_box')
|
||||
self.theme.font_footer_name = self.footer_area_page.font_name
|
||||
self.theme.font_footer_size = self.footer_area_page.font_size
|
||||
# position page (main)
|
||||
self.theme.font_main_override = not self.area_position_page.use_main_default_location
|
||||
if self.theme.font_main_override:
|
||||
self.theme.font_main_x = self.field('main_position_x')
|
||||
self.theme.font_main_y = self.field('main_position_y')
|
||||
self.theme.font_main_height = self.field('main_position_height')
|
||||
self.theme.font_main_width = self.field('main_position_width')
|
||||
self.theme.font_main_x = self.area_position_page.main_x
|
||||
self.theme.font_main_y = self.area_position_page.main_y
|
||||
self.theme.font_main_height = self.area_position_page.main_height
|
||||
self.theme.font_main_width = self.area_position_page.main_width
|
||||
else:
|
||||
self.theme.set_default_header()
|
||||
# position page (footer)
|
||||
self.theme.font_footer_override = not self.area_position_page.use_footer_default_location
|
||||
if self.theme.font_footer_override:
|
||||
self.theme.font_footer_x = self.field('footer_position_x')
|
||||
self.theme.font_footer_y = self.field('footer_position_y')
|
||||
self.theme.font_footer_height = self.field('footer_position_height')
|
||||
self.theme.font_footer_width = self.field('footer_position_width')
|
||||
self.theme.font_footer_x = self.area_position_page.footer_x
|
||||
self.theme.font_footer_y = self.area_position_page.footer_y
|
||||
self.theme.font_footer_height = self.area_position_page.footer_height
|
||||
self.theme.font_footer_width = self.area_position_page.footer_width
|
||||
else:
|
||||
self.theme.set_default_footer()
|
||||
# position page
|
||||
self.theme.display_horizontal_align = self.horizontal_combo_box.currentIndex()
|
||||
self.theme.display_vertical_align = self.vertical_combo_box.currentIndex()
|
||||
self.theme.display_slide_transition = self.field('slide_transition')
|
||||
self.theme.display_slide_transition_type = self.field('slide_transition_type')
|
||||
self.theme.display_slide_transition_speed = self.field('slide_transition_speed')
|
||||
# alignment page
|
||||
self.theme.display_horizontal_align = self.alignment_page.horizontal_align
|
||||
self.theme.display_vertical_align = self.alignment_page.vertical_align
|
||||
self.theme.display_slide_transition = self.alignment_page.is_transition_enabled
|
||||
self.theme.display_slide_transition_type = self.alignment_page.transition_type
|
||||
self.theme.display_slide_transition_speed = self.alignment_page.transition_speed
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Lets save the theme as Finish has been triggered
|
||||
"""
|
||||
# Save the theme name
|
||||
self.theme.theme_name = self.field('name')
|
||||
self.theme.theme_name = self.theme_name_edit.text()
|
||||
if not self.theme.theme_name:
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeWizard', 'Theme Name Missing'),
|
||||
@ -542,7 +390,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
return
|
||||
destination_path = None
|
||||
if self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or \
|
||||
self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
|
||||
self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
|
||||
file_name = self.theme.background_filename.name
|
||||
destination_path = self.path / self.theme.theme_name / file_name
|
||||
if not self.edit_mode and not self.theme_manager.check_if_theme_exists(self.theme.theme_name):
|
||||
|
@ -24,16 +24,15 @@ The Create/Edit theme wizard
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import is_macosx
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.display.render import ThemePreviewRenderer
|
||||
from openlp.core.lib.theme import BackgroundGradientType, BackgroundType, HorizontalType, TransitionType, \
|
||||
TransitionSpeed
|
||||
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
|
||||
from openlp.core.lib.ui import add_welcome_page
|
||||
from openlp.core.pages.alignment import AlignmentTransitionsPage
|
||||
from openlp.core.pages.areaposition import AreaPositionPage
|
||||
from openlp.core.pages.background import BackgroundPage
|
||||
from openlp.core.pages.fontselect import FontSelectPage
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
from openlp.core.widgets.edits import PathEdit
|
||||
from openlp.core.widgets.layouts import AspectRatioLayout
|
||||
from openlp.core.widgets.widgets import FontSelectWidget
|
||||
|
||||
|
||||
class Ui_ThemeWizard(object):
|
||||
@ -58,234 +57,26 @@ class Ui_ThemeWizard(object):
|
||||
# Welcome Page
|
||||
add_welcome_page(theme_wizard, ':/wizards/wizard_createtheme.bmp')
|
||||
# Background Page
|
||||
self.background_page = QtWidgets.QWizardPage()
|
||||
self.background_page = BackgroundPage()
|
||||
self.background_page.setObjectName('background_page')
|
||||
self.background_layout = QtWidgets.QVBoxLayout(self.background_page)
|
||||
self.background_layout.setObjectName('background_layout')
|
||||
self.background_type_layout = QtWidgets.QFormLayout()
|
||||
self.background_type_layout.setObjectName('background_type_layout')
|
||||
self.background_label = QtWidgets.QLabel(self.background_page)
|
||||
self.background_label.setObjectName('background_label')
|
||||
self.background_combo_box = QtWidgets.QComboBox(self.background_page)
|
||||
self.background_combo_box.addItems(['', '', '', ''])
|
||||
self.background_combo_box.setObjectName('background_combo_box')
|
||||
self.background_type_layout.addRow(self.background_label, self.background_combo_box)
|
||||
self.background_type_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.background_layout.addLayout(self.background_type_layout)
|
||||
self.background_stack = QtWidgets.QStackedLayout()
|
||||
self.background_stack.setObjectName('background_stack')
|
||||
self.color_widget = QtWidgets.QWidget(self.background_page)
|
||||
self.color_widget.setObjectName('color_widget')
|
||||
self.color_layout = QtWidgets.QFormLayout(self.color_widget)
|
||||
self.color_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.color_layout.setObjectName('color_layout')
|
||||
self.color_label = QtWidgets.QLabel(self.color_widget)
|
||||
self.color_label.setObjectName('color_label')
|
||||
self.color_button = ColorButton(self.color_widget)
|
||||
self.color_button.setObjectName('color_button')
|
||||
self.color_layout.addRow(self.color_label, self.color_button)
|
||||
self.color_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.background_stack.addWidget(self.color_widget)
|
||||
self.gradient_widget = QtWidgets.QWidget(self.background_page)
|
||||
self.gradient_widget.setObjectName('Gradient_widget')
|
||||
self.gradient_layout = QtWidgets.QFormLayout(self.gradient_widget)
|
||||
self.gradient_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gradient_layout.setObjectName('gradient_layout')
|
||||
self.gradient_start_label = QtWidgets.QLabel(self.gradient_widget)
|
||||
self.gradient_start_label.setObjectName('gradient_start_label')
|
||||
self.gradient_start_button = ColorButton(self.gradient_widget)
|
||||
self.gradient_start_button.setObjectName('gradient_start_button')
|
||||
self.gradient_layout.addRow(self.gradient_start_label, self.gradient_start_button)
|
||||
self.gradient_end_label = QtWidgets.QLabel(self.gradient_widget)
|
||||
self.gradient_end_label.setObjectName('gradient_end_label')
|
||||
self.gradient_end_button = ColorButton(self.gradient_widget)
|
||||
self.gradient_end_button.setObjectName('gradient_end_button')
|
||||
self.gradient_layout.addRow(self.gradient_end_label, self.gradient_end_button)
|
||||
self.gradient_type_label = QtWidgets.QLabel(self.gradient_widget)
|
||||
self.gradient_type_label.setObjectName('Gradient_type_label')
|
||||
self.gradient_combo_box = QtWidgets.QComboBox(self.gradient_widget)
|
||||
self.gradient_combo_box.setObjectName('gradient_combo_box')
|
||||
self.gradient_combo_box.addItems(['', '', '', '', ''])
|
||||
self.gradient_layout.addRow(self.gradient_type_label, self.gradient_combo_box)
|
||||
self.gradient_layout.setItem(3, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.background_stack.addWidget(self.gradient_widget)
|
||||
self.image_widget = QtWidgets.QWidget(self.background_page)
|
||||
self.image_widget.setObjectName('image_widget')
|
||||
self.image_layout = QtWidgets.QFormLayout(self.image_widget)
|
||||
self.image_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.image_layout.setObjectName('image_layout')
|
||||
self.image_color_label = QtWidgets.QLabel(self.color_widget)
|
||||
self.image_color_label.setObjectName('image_color_label')
|
||||
self.image_color_button = ColorButton(self.color_widget)
|
||||
self.image_color_button.setObjectName('image_color_button')
|
||||
self.image_layout.addRow(self.image_color_label, self.image_color_button)
|
||||
self.image_label = QtWidgets.QLabel(self.image_widget)
|
||||
self.image_label.setObjectName('image_label')
|
||||
self.image_path_edit = PathEdit(self.image_widget,
|
||||
dialog_caption=translate('OpenLP.ThemeWizard', 'Select Image'),
|
||||
show_revert=False)
|
||||
self.image_layout.addRow(self.image_label, self.image_path_edit)
|
||||
self.image_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.background_stack.addWidget(self.image_widget)
|
||||
self.transparent_widget = QtWidgets.QWidget(self.background_page)
|
||||
self.transparent_widget.setObjectName('TransparentWidget')
|
||||
self.transparent_layout = QtWidgets.QFormLayout(self.transparent_widget)
|
||||
self.transparent_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.transparent_layout.setObjectName('Transparent_layout')
|
||||
self.background_stack.addWidget(self.transparent_widget)
|
||||
self.background_layout.addLayout(self.background_stack)
|
||||
self.video_widget = QtWidgets.QWidget(self.background_page)
|
||||
self.video_widget.setObjectName('video_widget')
|
||||
self.video_layout = QtWidgets.QFormLayout(self.video_widget)
|
||||
self.video_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.video_layout.setObjectName('video_layout')
|
||||
self.video_color_label = QtWidgets.QLabel(self.color_widget)
|
||||
self.video_color_label.setObjectName('video_color_label')
|
||||
self.video_color_button = ColorButton(self.color_widget)
|
||||
self.video_color_button.setObjectName('video_color_button')
|
||||
self.video_layout.addRow(self.video_color_label, self.video_color_button)
|
||||
self.video_label = QtWidgets.QLabel(self.video_widget)
|
||||
self.video_label.setObjectName('video_label')
|
||||
self.video_path_edit = PathEdit(self.video_widget,
|
||||
dialog_caption=translate('OpenLP.ThemeWizard', 'Select Video'),
|
||||
show_revert=False)
|
||||
self.video_layout.addRow(self.video_label, self.video_path_edit)
|
||||
self.video_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.background_stack.addWidget(self.video_widget)
|
||||
theme_wizard.addPage(self.background_page)
|
||||
# Main Area Page
|
||||
self.main_area_page = QtWidgets.QWizardPage()
|
||||
self.main_area_page = FontSelectPage()
|
||||
self.main_area_page.setObjectName('main_area_page')
|
||||
self.main_area_layout = QtWidgets.QVBoxLayout(self.main_area_page)
|
||||
self.main_area_layout.setObjectName('main_area_layout')
|
||||
self.main_font = FontSelectWidget(self.main_area_page)
|
||||
self.main_area_layout.addWidget(self.main_font)
|
||||
theme_wizard.addPage(self.main_area_page)
|
||||
# Footer Area Page
|
||||
self.footer_area_page = QtWidgets.QWizardPage()
|
||||
self.footer_area_page = FontSelectPage()
|
||||
self.footer_area_page.setObjectName('footer_area_page')
|
||||
self.footer_area_layout = QtWidgets.QFormLayout(self.footer_area_page)
|
||||
self.footer_area_layout.setObjectName('footer_area_layout')
|
||||
self.footer_font_label = QtWidgets.QLabel(self.footer_area_page)
|
||||
self.footer_font_label.setObjectName('FooterFontLabel')
|
||||
self.footer_font_combo_box = QtWidgets.QFontComboBox(self.footer_area_page)
|
||||
self.footer_font_combo_box.setObjectName('footer_font_combo_box')
|
||||
self.footer_area_layout.addRow(self.footer_font_label, self.footer_font_combo_box)
|
||||
self.footer_color_label = QtWidgets.QLabel(self.footer_area_page)
|
||||
self.footer_color_label.setObjectName('footer_color_label')
|
||||
self.footer_color_button = ColorButton(self.footer_area_page)
|
||||
self.footer_color_button.setObjectName('footer_color_button')
|
||||
self.footer_area_layout.addRow(self.footer_color_label, self.footer_color_button)
|
||||
self.footer_size_label = QtWidgets.QLabel(self.footer_area_page)
|
||||
self.footer_size_label.setObjectName('footer_size_label')
|
||||
self.footer_size_spin_box = QtWidgets.QSpinBox(self.footer_area_page)
|
||||
self.footer_size_spin_box.setMaximum(999)
|
||||
self.footer_size_spin_box.setValue(10)
|
||||
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, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.footer_area_page.disable_features(FontSelectPage.Outline, FontSelectPage.Shadow,
|
||||
FontSelectPage.LineSpacing)
|
||||
theme_wizard.addPage(self.footer_area_page)
|
||||
# Alignment Page
|
||||
self.alignment_page = QtWidgets.QWizardPage()
|
||||
self.alignment_page = AlignmentTransitionsPage()
|
||||
self.alignment_page.setObjectName('alignment_page')
|
||||
self.alignment_layout = QtWidgets.QFormLayout(self.alignment_page)
|
||||
self.alignment_layout.setObjectName('alignment_layout')
|
||||
self.horizontal_label = QtWidgets.QLabel(self.alignment_page)
|
||||
self.horizontal_label.setObjectName('horizontal_label')
|
||||
self.horizontal_combo_box = QtWidgets.QComboBox(self.alignment_page)
|
||||
self.horizontal_combo_box.addItems(['', '', '', ''])
|
||||
self.horizontal_combo_box.setObjectName('horizontal_combo_box')
|
||||
self.alignment_layout.addRow(self.horizontal_label, self.horizontal_combo_box)
|
||||
self.vertical_label, self.vertical_combo_box = create_valign_selection_widgets(self.alignment_page)
|
||||
self.vertical_label.setObjectName('vertical_label')
|
||||
self.vertical_combo_box.setObjectName('vertical_combo_box')
|
||||
self.alignment_layout.addRow(self.vertical_label, self.vertical_combo_box)
|
||||
self.transitions_check_box = QtWidgets.QCheckBox(self.alignment_page)
|
||||
self.transitions_check_box.setObjectName('transitions_check_box')
|
||||
self.transition_layout = QtWidgets.QHBoxLayout()
|
||||
self.transition_layout.setObjectName("transition_layout")
|
||||
self.transition_combo_box = QtWidgets.QComboBox(self.alignment_page)
|
||||
self.transition_combo_box.setObjectName("transition_combo_box")
|
||||
self.transition_combo_box.addItems(['', '', '', '', ''])
|
||||
self.transition_layout.addWidget(self.transition_combo_box)
|
||||
self.transition_speed_label = QtWidgets.QLabel(self.alignment_page)
|
||||
self.transition_speed_label.setObjectName("transition_speed_label")
|
||||
self.transition_layout.addWidget(self.transition_speed_label)
|
||||
self.transition_speed_combo_box = QtWidgets.QComboBox(self.alignment_page)
|
||||
self.transition_speed_combo_box.setObjectName("transition_speed_combo_box")
|
||||
self.transition_speed_combo_box.addItems(['', '', ''])
|
||||
self.transition_layout.addWidget(self.transition_speed_combo_box)
|
||||
self.alignment_layout.addRow(self.transitions_check_box, self.transition_layout)
|
||||
theme_wizard.addPage(self.alignment_page)
|
||||
# Area Position Page
|
||||
self.area_position_page = QtWidgets.QWizardPage()
|
||||
self.area_position_page = AreaPositionPage()
|
||||
self.area_position_page.setObjectName('area_position_page')
|
||||
self.area_position_layout = QtWidgets.QHBoxLayout(self.area_position_page)
|
||||
self.area_position_layout.setObjectName('area_position_layout')
|
||||
self.main_position_group_box = QtWidgets.QGroupBox(self.area_position_page)
|
||||
self.main_position_group_box.setObjectName('main_position_group_box')
|
||||
self.main_position_layout = QtWidgets.QFormLayout(self.main_position_group_box)
|
||||
self.main_position_layout.setObjectName('main_position_layout')
|
||||
self.main_position_check_box = QtWidgets.QCheckBox(self.main_position_group_box)
|
||||
self.main_position_check_box.setObjectName('main_position_check_box')
|
||||
self.main_position_layout.addRow(self.main_position_check_box)
|
||||
self.main_x_label = QtWidgets.QLabel(self.main_position_group_box)
|
||||
self.main_x_label.setObjectName('main_x_label')
|
||||
self.main_x_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_x_spin_box.setMaximum(9999)
|
||||
self.main_x_spin_box.setObjectName('main_x_spin_box')
|
||||
self.main_position_layout.addRow(self.main_x_label, self.main_x_spin_box)
|
||||
self.main_y_label = QtWidgets.QLabel(self.main_position_group_box)
|
||||
self.main_y_label.setObjectName('main_y_label')
|
||||
self.main_y_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_y_spin_box.setMaximum(9999)
|
||||
self.main_y_spin_box.setObjectName('main_y_spin_box')
|
||||
self.main_position_layout.addRow(self.main_y_label, self.main_y_spin_box)
|
||||
self.main_width_label = QtWidgets.QLabel(self.main_position_group_box)
|
||||
self.main_width_label.setObjectName('main_width_label')
|
||||
self.main_width_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_width_spin_box.setMaximum(9999)
|
||||
self.main_width_spin_box.setObjectName('main_width_spin_box')
|
||||
self.main_position_layout.addRow(self.main_width_label, self.main_width_spin_box)
|
||||
self.main_height_label = QtWidgets.QLabel(self.main_position_group_box)
|
||||
self.main_height_label.setObjectName('main_height_label')
|
||||
self.main_height_spin_box = QtWidgets.QSpinBox(self.main_position_group_box)
|
||||
self.main_height_spin_box.setMaximum(9999)
|
||||
self.main_height_spin_box.setObjectName('main_height_spin_box')
|
||||
self.main_position_layout.addRow(self.main_height_label, self.main_height_spin_box)
|
||||
self.area_position_layout.addWidget(self.main_position_group_box)
|
||||
self.footer_position_group_box = QtWidgets.QGroupBox(self.area_position_page)
|
||||
self.footer_position_group_box.setObjectName('footer_position_group_box')
|
||||
self.footer_position_layout = QtWidgets.QFormLayout(self.footer_position_group_box)
|
||||
self.footer_position_layout.setObjectName('footer_position_layout')
|
||||
self.footer_position_check_box = QtWidgets.QCheckBox(self.footer_position_group_box)
|
||||
self.footer_position_check_box.setObjectName('footer_position_check_box')
|
||||
self.footer_position_layout.addRow(self.footer_position_check_box)
|
||||
self.footer_x_label = QtWidgets.QLabel(self.footer_position_group_box)
|
||||
self.footer_x_label.setObjectName('footer_x_label')
|
||||
self.footer_x_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_x_spin_box.setMaximum(9999)
|
||||
self.footer_x_spin_box.setObjectName('footer_x_spin_box')
|
||||
self.footer_position_layout.addRow(self.footer_x_label, self.footer_x_spin_box)
|
||||
self.footer_y_label = QtWidgets.QLabel(self.footer_position_group_box)
|
||||
self.footer_y_label.setObjectName('footer_y_label')
|
||||
self.footer_y_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_y_spin_box.setMaximum(9999)
|
||||
self.footer_y_spin_box.setObjectName('footer_y_spin_box')
|
||||
self.footer_position_layout.addRow(self.footer_y_label, self.footer_y_spin_box)
|
||||
self.footer_width_label = QtWidgets.QLabel(self.footer_position_group_box)
|
||||
self.footer_width_label.setObjectName('footer_width_label')
|
||||
self.footer_width_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_width_spin_box.setMaximum(9999)
|
||||
self.footer_width_spin_box.setObjectName('footer_width_spin_box')
|
||||
self.footer_position_layout.addRow(self.footer_width_label, self.footer_width_spin_box)
|
||||
self.footer_height_label = QtWidgets.QLabel(self.footer_position_group_box)
|
||||
self.footer_height_label.setObjectName('footer_height_label')
|
||||
self.footer_height_spin_box = QtWidgets.QSpinBox(self.footer_position_group_box)
|
||||
self.footer_height_spin_box.setMaximum(9999)
|
||||
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)
|
||||
theme_wizard.addPage(self.area_position_page)
|
||||
# Preview Page
|
||||
self.preview_page = QtWidgets.QWizardPage()
|
||||
@ -313,15 +104,6 @@ class Ui_ThemeWizard(object):
|
||||
self.preview_layout.addWidget(self.preview_area)
|
||||
theme_wizard.addPage(self.preview_page)
|
||||
self.retranslate_ui(theme_wizard)
|
||||
self.background_combo_box.currentIndexChanged.connect(self.background_stack.setCurrentIndex)
|
||||
self.main_position_check_box.toggled.connect(self.main_x_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_y_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_width_spin_box.setDisabled)
|
||||
self.main_position_check_box.toggled.connect(self.main_height_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_x_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_y_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_width_spin_box.setDisabled)
|
||||
self.footer_position_check_box.toggled.connect(self.footer_height_spin_box.setDisabled)
|
||||
|
||||
def retranslate_ui(self, theme_wizard):
|
||||
"""
|
||||
@ -336,87 +118,20 @@ class Ui_ThemeWizard(object):
|
||||
self.background_page.setTitle(translate('OpenLP.ThemeWizard', 'Set Up Background'))
|
||||
self.background_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Set up your theme\'s background '
|
||||
'according to the parameters below.'))
|
||||
self.background_label.setText(translate('OpenLP.ThemeWizard', 'Background type:'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Solid, translate('OpenLP.ThemeWizard', 'Solid color'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Gradient, translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Image, UiStrings().Image)
|
||||
self.background_combo_box.setItemText(BackgroundType.Transparent,
|
||||
translate('OpenLP.ThemeWizard', 'Transparent'))
|
||||
self.color_label.setText(translate('OpenLP.ThemeWizard', 'color:'))
|
||||
self.gradient_start_label.setText(translate('OpenLP.ThemeWizard', 'Starting color:'))
|
||||
self.gradient_end_label.setText(translate('OpenLP.ThemeWizard', 'Ending color:'))
|
||||
self.gradient_type_label.setText(translate('OpenLP.ThemeWizard', 'Gradient:'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Horizontal,
|
||||
translate('OpenLP.ThemeWizard', 'Horizontal'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Vertical,
|
||||
translate('OpenLP.ThemeWizard', 'Vertical'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.Circular,
|
||||
translate('OpenLP.ThemeWizard', 'Circular'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftTop,
|
||||
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
||||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftBottom,
|
||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||
self.image_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.image_label.setText('{text}:'.format(text=UiStrings().Image))
|
||||
self.video_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.video_label.setText('{text}:'.format(text=UiStrings().Video))
|
||||
self.main_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
||||
self.main_area_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Define the font and display '
|
||||
'characteristics for the Display text'))
|
||||
self.footer_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Footer Area Font Details'))
|
||||
self.footer_area_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Define the font and display '
|
||||
'characteristics for the Footer text'))
|
||||
self.footer_font_label.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
||||
self.footer_color_label.setText(translate('OpenLP.ThemeWizard', 'color:'))
|
||||
self.footer_size_label.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||
self.footer_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
|
||||
self.alignment_page.setTitle(translate('OpenLP.ThemeWizard', 'Text Formatting Details'))
|
||||
self.alignment_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Allows additional display '
|
||||
'formatting information to be defined'))
|
||||
self.horizontal_label.setText(translate('OpenLP.ThemeWizard', 'Horizontal Align:'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Left, translate('OpenLP.ThemeWizard', 'Left'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Right, translate('OpenLP.ThemeWizard', 'Right'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Center, translate('OpenLP.ThemeWizard', 'Center'))
|
||||
self.horizontal_combo_box.setItemText(HorizontalType.Justify, translate('OpenLP.ThemeWizard', 'Justify'))
|
||||
self.transitions_check_box.setText(translate('OpenLP.ThemeWizard', 'Transitions:'))
|
||||
self.transition_combo_box.setItemText(TransitionType.Fade, translate('OpenLP.ThemeWizard', 'Fade'))
|
||||
self.transition_combo_box.setItemText(TransitionType.Slide, translate('OpenLP.ThemeWizard', 'Slide'))
|
||||
self.transition_combo_box.setItemText(TransitionType.Concave, translate('OpenLP.ThemeWizard', 'Concave'))
|
||||
self.transition_combo_box.setItemText(TransitionType.Convex, translate('OpenLP.ThemeWizard', 'Convex'))
|
||||
self.transition_combo_box.setItemText(TransitionType.Zoom, translate('OpenLP.ThemeWizard', 'Zoom'))
|
||||
self.transition_speed_label.setText(translate('OpenLP.ThemeWizard', 'Speed:'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Normal, translate('OpenLP.ThemeWizard', 'Normal'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Fast, translate('OpenLP.ThemeWizard', 'Fast'))
|
||||
self.transition_speed_combo_box.setItemText(TransitionSpeed.Slow, translate('OpenLP.ThemeWizard', 'Slow'))
|
||||
self.area_position_page.setTitle(translate('OpenLP.ThemeWizard', 'Output Area Locations'))
|
||||
self.area_position_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Allows you to change and move the'
|
||||
' Main and Footer areas.'))
|
||||
self.main_position_group_box.setTitle(translate('OpenLP.ThemeWizard', '&Main Area'))
|
||||
self.main_position_check_box.setText(translate('OpenLP.ThemeWizard', '&Use default location'))
|
||||
self.main_x_label.setText(translate('OpenLP.ThemeWizard', 'X position:'))
|
||||
self.main_x_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_y_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_y_label.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
|
||||
self.main_width_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_width_label.setText(translate('OpenLP.ThemeWizard', 'Width:'))
|
||||
self.main_height_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.main_height_label.setText(translate('OpenLP.ThemeWizard', 'Height:'))
|
||||
self.footer_position_group_box.setTitle(translate('OpenLP.ThemeWizard', '&Footer Area'))
|
||||
self.footer_x_label.setText(translate('OpenLP.ThemeWizard', 'X position:'))
|
||||
self.footer_x_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.footer_y_label.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
|
||||
self.footer_y_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
self.footer_width_label.setText(translate('OpenLP.ThemeWizard', 'Width:'))
|
||||
self.footer_width_spin_box.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
|
||||
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'))
|
||||
theme_wizard.setOption(QtWidgets.QWizard.HaveCustomButton1, False)
|
||||
theme_wizard.setButtonText(QtWidgets.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:'))
|
||||
# Align all QFormLayouts towards each other.
|
||||
label_width = max(self.background_label.minimumSizeHint().width(),
|
||||
self.horizontal_label.minimumSizeHint().width())
|
||||
self.spacer.changeSize(label_width, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
|
0
openlp/core/widgets/dialogs.py
Executable file → Normal file
0
openlp/core/widgets/dialogs.py
Executable file → Normal file
@ -19,34 +19,15 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.ui.themeform package.
|
||||
The :mod:`~openlp.core.widgets.labels` module contains specialised labels
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.ui.themeform import ThemeForm
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
|
||||
class TestThemeForm(TestCase):
|
||||
class FormLabel(QtWidgets.QLabel):
|
||||
"""
|
||||
Test the functions in the ThemeForm Class
|
||||
A label that is prepped for forms, right aligned and vertically centered
|
||||
"""
|
||||
def setUp(self):
|
||||
with patch('openlp.core.ui.themeform.ThemeForm._setup'):
|
||||
self.instance = ThemeForm(None)
|
||||
|
||||
def test_on_image_path_edit_path_changed(self):
|
||||
"""
|
||||
Test the `image_path_edit.pathChanged` handler
|
||||
"""
|
||||
# GIVEN: An instance of Theme Form
|
||||
with patch.object(self.instance, 'set_background_page_values') as mocked_set_background_page_values:
|
||||
self.instance.theme = MagicMock()
|
||||
|
||||
# WHEN: `on_image_path_edit_path_changed` is clicked
|
||||
self.instance.on_image_path_edit_path_changed(Path('/', 'new', 'pat.h'))
|
||||
|
||||
# THEN: The theme background file should be set and `set_background_page_values` should have been called
|
||||
assert self.instance.theme.background_filename == Path('/', 'new', 'pat.h')
|
||||
mocked_set_background_page_values.assert_called_once_with()
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
@ -21,13 +21,11 @@
|
||||
"""
|
||||
The :mod:`~openlp.core.widgets.widgets` module contains custom widgets used in OpenLP
|
||||
"""
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.settings import ProxyMode, Settings
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
|
||||
|
||||
SCREENS_LAYOUT_STYLE = """
|
||||
@ -443,350 +441,3 @@ class ScreenSelectionWidget(QtWidgets.QWidget):
|
||||
self._setup_spin_box(self.height_spin_box, 0, screen.display_geometry.height(),
|
||||
screen.display_geometry.height())
|
||||
self.current_screen = screen
|
||||
|
||||
|
||||
class FontSelectWidget(QtWidgets.QWidget):
|
||||
"""
|
||||
A font selection widget
|
||||
"""
|
||||
Outline = 'outline'
|
||||
Shadow = 'shadow'
|
||||
LineSpacing = 'line_spacing'
|
||||
|
||||
font_name_changed = QtCore.pyqtSignal(str)
|
||||
font_size_changed = QtCore.pyqtSignal(int)
|
||||
font_color_changed = QtCore.pyqtSignal(str)
|
||||
is_bold_changed = QtCore.pyqtSignal(bool)
|
||||
is_italic_changed = QtCore.pyqtSignal(bool)
|
||||
line_spacing_changed = QtCore.pyqtSignal(int)
|
||||
is_outline_enabled_changed = QtCore.pyqtSignal(bool)
|
||||
outline_color_changed = QtCore.pyqtSignal(str)
|
||||
outline_size_changed = QtCore.pyqtSignal(int)
|
||||
is_shadow_enabled_changed = QtCore.pyqtSignal(bool)
|
||||
shadow_color_changed = QtCore.pyqtSignal(str)
|
||||
shadow_size_changed = QtCore.pyqtSignal(int)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._column_width = 0
|
||||
self.setup_ui()
|
||||
self.feature_widgets = {
|
||||
FontSelectWidget.Outline: [self.outline_groupbox],
|
||||
FontSelectWidget.Shadow: [self.shadow_groupbox],
|
||||
FontSelectWidget.LineSpacing: [self.line_spacing_label, self.line_spacing_spinbox]
|
||||
}
|
||||
|
||||
def setup_ui(self):
|
||||
self.layout = QtWidgets.QGridLayout(self)
|
||||
# Font name
|
||||
self.font_name_label = QtWidgets.QLabel(self)
|
||||
self.font_name_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.font_name_label.setObjectName('font_name_label')
|
||||
self.layout.addWidget(self.font_name_label, 0, 0)
|
||||
self.font_name_combobox = QtWidgets.QFontComboBox(self)
|
||||
self.font_name_combobox.setObjectName('font_name_combobox')
|
||||
self.layout.addWidget(self.font_name_combobox, 0, 1, 1, 3)
|
||||
# Font color
|
||||
self.font_color_label = QtWidgets.QLabel(self)
|
||||
self.font_color_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.font_color_label.setObjectName('font_color_label')
|
||||
self.layout.addWidget(self.font_color_label, 1, 0)
|
||||
self.font_color_button = ColorButton(self)
|
||||
self.font_color_button.setObjectName('font_color_button')
|
||||
self.layout.addWidget(self.font_color_button, 1, 1)
|
||||
# Font style
|
||||
self.font_style_label = QtWidgets.QLabel(self)
|
||||
self.font_style_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.font_style_label.setObjectName('font_style_label')
|
||||
self.layout.addWidget(self.font_style_label, 1, 2)
|
||||
self.style_layout = QtWidgets.QHBoxLayout()
|
||||
self.style_bold_button = QtWidgets.QToolButton(self)
|
||||
self.style_bold_button.setIcon(UiIcons().bold)
|
||||
self.style_bold_button.setShortcut(QtGui.QKeySequence(QtGui.QKeySequence.Bold))
|
||||
self.style_bold_button.setObjectName('style_bold_button')
|
||||
self.style_layout.addWidget(self.style_bold_button)
|
||||
self.style_italic_button = QtWidgets.QToolButton(self)
|
||||
self.style_italic_button.setIcon(UiIcons().italic)
|
||||
self.style_italic_button.setShortcut(QtGui.QKeySequence(QtGui.QKeySequence.Italic))
|
||||
self.style_italic_button.setObjectName('style_italic_button')
|
||||
self.style_layout.addWidget(self.style_italic_button)
|
||||
self.style_layout.addStretch(1)
|
||||
self.layout.addLayout(self.style_layout, 1, 3)
|
||||
# Font size
|
||||
self.font_size_label = QtWidgets.QLabel(self)
|
||||
self.font_size_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.font_size_label.setObjectName('font_size_label')
|
||||
self.layout.addWidget(self.font_size_label, 2, 0)
|
||||
self.font_size_spinbox = QtWidgets.QSpinBox(self)
|
||||
self.font_size_spinbox.setMaximum(999)
|
||||
self.font_size_spinbox.setValue(16)
|
||||
self.font_size_spinbox.setObjectName('font_size_spinbox')
|
||||
self.layout.addWidget(self.font_size_spinbox, 2, 1)
|
||||
# Line spacing
|
||||
self.line_spacing_label = QtWidgets.QLabel(self)
|
||||
self.line_spacing_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.line_spacing_label.setObjectName('line_spacing_label')
|
||||
self.layout.addWidget(self.line_spacing_label, 2, 2)
|
||||
self.line_spacing_spinbox = QtWidgets.QSpinBox(self)
|
||||
self.line_spacing_spinbox.setMinimum(-250)
|
||||
self.line_spacing_spinbox.setMaximum(250)
|
||||
self.line_spacing_spinbox.setObjectName('line_spacing_spinbox')
|
||||
self.layout.addWidget(self.line_spacing_spinbox, 2, 3)
|
||||
# Outline
|
||||
self.outline_groupbox = QtWidgets.QGroupBox(self)
|
||||
self.outline_groupbox.setCheckable(True)
|
||||
self.outline_groupbox.setChecked(False)
|
||||
self.outline_groupbox.setObjectName('outline_groupbox')
|
||||
self.outline_layout = QtWidgets.QGridLayout(self.outline_groupbox)
|
||||
self.layout.addWidget(self.outline_groupbox, 3, 0, 1, 2)
|
||||
# Outline colour
|
||||
self.outline_color_label = QtWidgets.QLabel(self.outline_groupbox)
|
||||
self.outline_color_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.outline_color_label.setObjectName('outline_color_label')
|
||||
self.outline_layout.addWidget(self.outline_color_label, 0, 0)
|
||||
self.outline_color_button = ColorButton(self.outline_groupbox)
|
||||
self.outline_color_button.setObjectName('outline_color_button')
|
||||
self.outline_layout.addWidget(self.outline_color_button, 0, 1)
|
||||
# Outline size
|
||||
self.outline_size_label = QtWidgets.QLabel(self.outline_groupbox)
|
||||
self.outline_size_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.outline_size_label.setObjectName('outline_size_label')
|
||||
self.outline_layout.addWidget(self.outline_size_label, 1, 0)
|
||||
self.outline_size_spinbox = QtWidgets.QSpinBox(self.outline_groupbox)
|
||||
self.outline_size_spinbox.setMaximum(9999)
|
||||
self.outline_size_spinbox.setObjectName('outline_size_spinbox')
|
||||
self.outline_layout.addWidget(self.outline_size_spinbox, 1, 1)
|
||||
# Shadow
|
||||
self.shadow_groupbox = QtWidgets.QGroupBox(self)
|
||||
self.shadow_groupbox.setCheckable(True)
|
||||
self.shadow_groupbox.setChecked(False)
|
||||
self.shadow_groupbox.setObjectName('shadow_groupbox')
|
||||
self.shadow_layout = QtWidgets.QGridLayout(self.shadow_groupbox)
|
||||
self.layout.addWidget(self.shadow_groupbox, 3, 2, 1, 2)
|
||||
# Shadow color
|
||||
self.shadow_color_label = QtWidgets.QLabel(self.shadow_groupbox)
|
||||
self.shadow_color_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.shadow_color_label.setObjectName('shadow_color_label')
|
||||
self.shadow_layout.addWidget(self.shadow_color_label, 0, 0)
|
||||
self.shadow_color_button = ColorButton(self.shadow_groupbox)
|
||||
self.shadow_color_button.setObjectName('shadow_color_button')
|
||||
self.shadow_layout.addWidget(self.shadow_color_button, 0, 1)
|
||||
# Shadow size
|
||||
self.shadow_size_label = QtWidgets.QLabel(self.shadow_groupbox)
|
||||
self.shadow_size_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.shadow_size_label.setObjectName('shadow_size_label')
|
||||
self.shadow_layout.addWidget(self.shadow_size_label, 1, 0)
|
||||
self.shadow_size_spinbox = QtWidgets.QSpinBox(self.shadow_groupbox)
|
||||
self.shadow_size_spinbox.setMaximum(9999)
|
||||
self.shadow_size_spinbox.setObjectName('shadow_size_spinbox')
|
||||
self.shadow_layout.addWidget(self.shadow_size_spinbox, 1, 1)
|
||||
# Fix the size
|
||||
self.resize_widgets()
|
||||
# Connect all the signals
|
||||
self.font_name_combobox.activated.connect(self._on_font_name_changed)
|
||||
self.font_color_button.colorChanged.connect(self._on_font_color_changed)
|
||||
self.style_bold_button.toggled.connect(self._on_style_bold_toggled)
|
||||
self.style_italic_button.toggled.connect(self._on_style_italic_toggled)
|
||||
self.font_size_spinbox.valueChanged.connect(self._on_font_size_changed)
|
||||
self.line_spacing_spinbox.valueChanged.connect(self._on_line_spacing_changed)
|
||||
self.outline_groupbox.toggled.connect(self._on_outline_toggled)
|
||||
self.outline_color_button.colorChanged.connect(self._on_outline_color_changed)
|
||||
self.outline_size_spinbox.valueChanged.connect(self._on_outline_size_changed)
|
||||
self.shadow_groupbox.toggled.connect(self._on_shadow_toggled)
|
||||
self.shadow_color_button.colorChanged.connect(self._on_shadow_color_changed)
|
||||
self.shadow_size_spinbox.valueChanged.connect(self._on_shadow_size_changed)
|
||||
# Translate everything
|
||||
self.retranslate_ui()
|
||||
|
||||
def retranslate_ui(self):
|
||||
self.font_name_label.setText(translate('OpenLP.FontSelectWidget', 'Font:'))
|
||||
self.font_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.font_style_label.setText(translate('OpenLP.FontSelectWidget', 'Style:'))
|
||||
self.style_bold_button.setToolTip('{name} ({shortcut})'.format(
|
||||
name=translate('OpenLP.FontSelectWidget', 'Bold'),
|
||||
shortcut=QtGui.QKeySequence(QtGui.QKeySequence.Bold).toString()
|
||||
))
|
||||
self.style_italic_button.setToolTip('{name} ({shortcut})'.format(
|
||||
name=translate('OpenLP.FontSelectWidget', 'Italic'),
|
||||
shortcut=QtGui.QKeySequence(QtGui.QKeySequence.Italic).toString()
|
||||
))
|
||||
self.font_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
self.font_size_spinbox.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit))
|
||||
self.line_spacing_label.setText(translate('OpenLP.FontSelectWidget', 'Line Spacing:'))
|
||||
self.outline_groupbox.setTitle(translate('OpenLP.FontSelectWidget', 'Outline'))
|
||||
self.outline_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.outline_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
self.shadow_groupbox.setTitle(translate('OpenLP.FontSelectWidget', 'Shadow'))
|
||||
self.shadow_color_label.setText(translate('OpenLP.FontSelectWidget', 'Color:'))
|
||||
self.shadow_size_label.setText(translate('OpenLP.FontSelectWidget', 'Size:'))
|
||||
|
||||
def resizeEvent(self, event):
|
||||
"""
|
||||
Override inherited resize method
|
||||
"""
|
||||
super().resizeEvent(event)
|
||||
self.resize_widgets()
|
||||
|
||||
def _on_font_name_changed(self, name):
|
||||
if isinstance(name, str):
|
||||
self.font_name_changed.emit(name)
|
||||
|
||||
def _on_font_color_changed(self, color):
|
||||
self.font_color_changed.emit(color)
|
||||
|
||||
def _on_style_bold_toggled(self, is_bold):
|
||||
self.is_bold_changed.emit(is_bold)
|
||||
|
||||
def _on_style_italic_toggled(self, is_italic):
|
||||
self.is_italic_changed.emit(is_italic)
|
||||
|
||||
def _on_font_size_changed(self, size):
|
||||
self.font_size_changed.emit(size)
|
||||
|
||||
def _on_line_spacing_changed(self, spacing):
|
||||
self.line_spacing_changed.emit(spacing)
|
||||
|
||||
def _on_outline_toggled(self, is_enabled):
|
||||
self.is_outline_enabled_changed.emit(is_enabled)
|
||||
|
||||
def _on_outline_color_changed(self, color):
|
||||
self.outline_color_changed.emit(color)
|
||||
|
||||
def _on_outline_size_changed(self, size):
|
||||
self.outline_size_changed.emit(size)
|
||||
|
||||
def _on_shadow_toggled(self, is_enabled):
|
||||
self.is_shadow_enabled_changed.emit(is_enabled)
|
||||
|
||||
def _on_shadow_color_changed(self, color):
|
||||
self.shadow_color_changed.emit(color)
|
||||
|
||||
def _on_shadow_size_changed(self, size):
|
||||
self.shadow_size_changed.emit(size)
|
||||
|
||||
def resize_widgets(self):
|
||||
"""
|
||||
Resize all the widgets and set the column widths
|
||||
"""
|
||||
width = self.geometry().width()
|
||||
margins = self.layout.contentsMargins()
|
||||
spacing = self.layout.horizontalSpacing()
|
||||
self._column_width = (width - margins.left() - margins.right() - (spacing * 3)) // 4
|
||||
for column_number in range(4):
|
||||
self.layout.setColumnMinimumWidth(column_number, self._column_width)
|
||||
|
||||
def enable_features(self, *features):
|
||||
"""
|
||||
Enable a feature
|
||||
"""
|
||||
for feature_name in features:
|
||||
if feature_name not in self.feature_widgets.keys():
|
||||
raise KeyError('No such feature: {feature_name}'.format(feature_name=feature_name))
|
||||
for widget in self.feature_widgets[feature_name]:
|
||||
widget.show()
|
||||
|
||||
def disable_features(self, *features):
|
||||
"""
|
||||
Disable a feature
|
||||
"""
|
||||
for feature_name in features:
|
||||
if feature_name not in self.feature_widgets.keys():
|
||||
raise KeyError('No such feature: {feature_name}'.format(feature_name=feature_name))
|
||||
for widget in self.feature_widgets[feature_name]:
|
||||
widget.hide()
|
||||
|
||||
@property
|
||||
def font_name(self):
|
||||
return self.font_name_combobox.currentFont().family()
|
||||
|
||||
@font_name.setter
|
||||
def font_name(self, font):
|
||||
self.font_name_combobox.setCurrentFont(QtGui.QFont(font))
|
||||
|
||||
@property
|
||||
def font_color(self):
|
||||
return self.font_color_button.color
|
||||
|
||||
@font_color.setter
|
||||
def font_color(self, color):
|
||||
self.font_color_button.color = color
|
||||
|
||||
@property
|
||||
def is_bold(self):
|
||||
return self.style_bold_button.isChecked()
|
||||
|
||||
@is_bold.setter
|
||||
def is_bold(self, is_bold):
|
||||
self.style_bold_button.setChecked(is_bold)
|
||||
|
||||
@property
|
||||
def is_italic(self):
|
||||
return self.style_italic_button.isChecked()
|
||||
|
||||
@is_italic.setter
|
||||
def is_italic(self, is_italic):
|
||||
self.style_italic_button.setChecked(is_italic)
|
||||
|
||||
@property
|
||||
def font_size(self):
|
||||
return self.font_size_spinbox.value()
|
||||
|
||||
@font_size.setter
|
||||
def font_size(self, size):
|
||||
self.font_size_spinbox.setValue(size)
|
||||
|
||||
@property
|
||||
def line_spacing(self):
|
||||
return self.line_spacing_spinbox.value()
|
||||
|
||||
@line_spacing.setter
|
||||
def line_spacing(self, line_spacing):
|
||||
self.line_spacing_spinbox.setValue(line_spacing)
|
||||
|
||||
@property
|
||||
def is_outline_enabled(self):
|
||||
return self.outline_groupbox.isChecked()
|
||||
|
||||
@is_outline_enabled.setter
|
||||
def is_outline_enabled(self, is_enabled):
|
||||
self.outline_groupbox.setChecked(is_enabled)
|
||||
|
||||
@property
|
||||
def outline_color(self):
|
||||
return self.outline_color_button.color
|
||||
|
||||
@outline_color.setter
|
||||
def outline_color(self, color):
|
||||
self.outline_color_button.color = color
|
||||
|
||||
@property
|
||||
def outline_size(self):
|
||||
return self.outline_size_spinbox.value()
|
||||
|
||||
@outline_size.setter
|
||||
def outline_size(self, size):
|
||||
self.outline_size_spinbox.setValue(size)
|
||||
|
||||
@property
|
||||
def is_shadow_enabled(self):
|
||||
return self.shadow_groupbox.isChecked()
|
||||
|
||||
@is_shadow_enabled.setter
|
||||
def is_shadow_enabled(self, is_enabled):
|
||||
self.shadow_groupbox.setChecked(is_enabled)
|
||||
|
||||
@property
|
||||
def shadow_color(self):
|
||||
return self.shadow_color_button.color
|
||||
|
||||
@shadow_color.setter
|
||||
def shadow_color(self, color):
|
||||
self.shadow_color_button.color = color
|
||||
|
||||
@property
|
||||
def shadow_size(self):
|
||||
return self.shadow_size_spinbox.value()
|
||||
|
||||
@shadow_size.setter
|
||||
def shadow_size(self, size):
|
||||
self.shadow_size_spinbox.setValue(size)
|
||||
|
23
tests/openlp_core/pages/__init__.py
Normal file
23
tests/openlp_core/pages/__init__.py
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.pages package.
|
||||
"""
|
305
tests/openlp_core/pages/test_alignment.py
Normal file
305
tests/openlp_core/pages/test_alignment.py
Normal file
@ -0,0 +1,305 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.pages.alignment package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from openlp.core.lib.theme import HorizontalType, VerticalType, TransitionType, TransitionSpeed
|
||||
from openlp.core.pages.alignment import AlignmentTransitionsPage
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestAlignmentTransitionsPage(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
def test_init_(self):
|
||||
"""
|
||||
Test the initialisation of AlignmentTransitionsPage
|
||||
"""
|
||||
# GIVEN: The AlignmentTransitionsPage class
|
||||
# WHEN: Initialising AlignmentTransitionsPage
|
||||
# THEN: We should have an instance of the widget with no errors
|
||||
AlignmentTransitionsPage()
|
||||
|
||||
def test_on_transition_enabled_changed(self):
|
||||
"""
|
||||
Test the _on_transition_enabled_changed() slot
|
||||
"""
|
||||
# GIVEN: And instance of AlignmentTransitionsPage and some mock widgets
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: _on_transition_enabled_changed
|
||||
page._on_transition_enabled_changed(True)
|
||||
|
||||
# THEN: The correct widgets should be visible
|
||||
assert page.transition_effect_label.isEnabled()
|
||||
assert page.transition_effect_combo_box.isEnabled()
|
||||
assert page.transition_speed_label.isEnabled()
|
||||
assert page.transition_speed_combo_box.isEnabled()
|
||||
|
||||
def test_get_horizontal_align(self):
|
||||
"""
|
||||
Test the horizontal_align getter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance with the combobox set to index 1
|
||||
page = AlignmentTransitionsPage()
|
||||
page.horizontal_combo_box.setCurrentIndex(1)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.horizontal_align
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == HorizontalType.Right
|
||||
|
||||
def test_set_horizontal_align_int(self):
|
||||
"""
|
||||
Test the horizontal_align setter with an int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.horizontal_align = HorizontalType.Center
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.horizontal_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_horizontal_align_str(self):
|
||||
"""
|
||||
Test the horizontal_align setter with a str
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.horizontal_align = HorizontalType.to_string(HorizontalType.Justify)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.horizontal_combo_box.currentIndex() == 3
|
||||
|
||||
def test_set_horizontal_align_exception(self):
|
||||
"""
|
||||
Test the horizontal_align setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='horizontal_align must either be a string or an int'):
|
||||
page.horizontal_align = []
|
||||
|
||||
def test_get_vertical_align(self):
|
||||
"""
|
||||
Test the vertical_align getter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance with the combobox set to index 1
|
||||
page = AlignmentTransitionsPage()
|
||||
page.vertical_combo_box.setCurrentIndex(1)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.vertical_align
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == VerticalType.Middle
|
||||
|
||||
def test_set_vertical_align_int(self):
|
||||
"""
|
||||
Test the vertical_align setter with an int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.vertical_align = VerticalType.Bottom
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.vertical_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_vertical_align_str(self):
|
||||
"""
|
||||
Test the vertical_align setter with a str
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.vertical_align = VerticalType.to_string(VerticalType.Top)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.vertical_combo_box.currentIndex() == 0
|
||||
|
||||
def test_set_vertical_align_exception(self):
|
||||
"""
|
||||
Test the vertical_align setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='vertical_align must either be a string or an int'):
|
||||
page.vertical_align = []
|
||||
|
||||
def test_get_is_transition_enabled(self):
|
||||
"""
|
||||
Test the is_transition_enabled getter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance with the transitions enabled
|
||||
page = AlignmentTransitionsPage()
|
||||
page.transitions_enabled_check_box.setChecked(False)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.is_transition_enabled
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_is_transition_enabled(self):
|
||||
"""
|
||||
Test the is_transition_enabled setter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
page._on_transition_enabled_changed = MagicMock()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.is_transition_enabled = True
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.transitions_enabled_check_box.isChecked() is True
|
||||
page._on_transition_enabled_changed.assert_called_once_with(True)
|
||||
|
||||
def test_get_transition_type(self):
|
||||
"""
|
||||
Test the transition_type getter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance with the combobox set to index 1
|
||||
page = AlignmentTransitionsPage()
|
||||
page.transition_effect_combo_box.setCurrentIndex(1)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.transition_type
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == TransitionType.Slide
|
||||
|
||||
def test_set_transition_type_int(self):
|
||||
"""
|
||||
Test the transition_type setter with an int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.transition_type = TransitionType.Concave
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.transition_effect_combo_box.currentIndex() == 3
|
||||
|
||||
def test_set_transition_type_str(self):
|
||||
"""
|
||||
Test the transition_type setter with a str
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.transition_type = TransitionType.to_string(TransitionType.Convex)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.transition_effect_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_transition_type_exception(self):
|
||||
"""
|
||||
Test the transition_type setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='transition_type must either be a string or an int'):
|
||||
page.transition_type = []
|
||||
|
||||
def test_get_transition_speed(self):
|
||||
"""
|
||||
Test the transition_speed getter
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance with the combobox set to index 1
|
||||
page = AlignmentTransitionsPage()
|
||||
page.transition_speed_combo_box.setCurrentIndex(0)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.transition_speed
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == TransitionSpeed.Normal
|
||||
|
||||
def test_set_transition_speed_int(self):
|
||||
"""
|
||||
Test the transition_speed setter with an int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.transition_speed = TransitionSpeed.Fast
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.transition_speed_combo_box.currentIndex() == 1
|
||||
|
||||
def test_set_transition_speed_str(self):
|
||||
"""
|
||||
Test the transition_speed setter with a str
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.transition_speed = TransitionSpeed.to_string(TransitionSpeed.Slow)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.transition_speed_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_transition_speed_exception(self):
|
||||
"""
|
||||
Test the transition_speed setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A AlignmentTransitionsPage instance
|
||||
page = AlignmentTransitionsPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='transition_speed must either be a string or an int'):
|
||||
page.transition_speed = []
|
318
tests/openlp_core/pages/test_areaposition.py
Normal file
318
tests/openlp_core/pages/test_areaposition.py
Normal file
@ -0,0 +1,318 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.pages.alignment package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.pages.areaposition import AreaPositionPage
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestAreaPositionPage(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
def test_init_(self):
|
||||
"""
|
||||
Test the initialisation of AreaPositionPage
|
||||
"""
|
||||
# GIVEN: The AreaPositionPage class
|
||||
# WHEN: Initialising AreaPositionPage
|
||||
# THEN: We should have an instance of the widget with no errors
|
||||
AreaPositionPage()
|
||||
|
||||
def test_get_use_main_default_location(self):
|
||||
"""
|
||||
Test the use_main_default_location getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to index 1
|
||||
page = AreaPositionPage()
|
||||
page.main_position_check_box.setChecked(False)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.use_main_default_location
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_use_main_default_location(self):
|
||||
"""
|
||||
Test the use_main_default_location setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.use_main_default_location = True
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.main_position_check_box.isChecked() is True
|
||||
|
||||
def test_get_main_x(self):
|
||||
"""
|
||||
Test the main_x getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to index 1
|
||||
page = AreaPositionPage()
|
||||
page.main_x_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.main_x
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_main_x(self):
|
||||
"""
|
||||
Test the main_x setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.main_x = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.main_x_spin_box.value() == 20
|
||||
|
||||
def test_get_main_y(self):
|
||||
"""
|
||||
Test the main_y getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indey 1
|
||||
page = AreaPositionPage()
|
||||
page.main_y_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.main_y
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_main_y(self):
|
||||
"""
|
||||
Test the main_y setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.main_y = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.main_y_spin_box.value() == 20
|
||||
|
||||
def test_get_main_width(self):
|
||||
"""
|
||||
Test the main_width getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indewidth 1
|
||||
page = AreaPositionPage()
|
||||
page.main_width_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.main_width
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_main_width(self):
|
||||
"""
|
||||
Test the main_width setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.main_width = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.main_width_spin_box.value() == 20
|
||||
|
||||
def test_get_main_height(self):
|
||||
"""
|
||||
Test the main_height getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indeheight 1
|
||||
page = AreaPositionPage()
|
||||
page.main_height_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.main_height
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_main_height(self):
|
||||
"""
|
||||
Test the main_height setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.main_height = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.main_height_spin_box.value() == 20
|
||||
|
||||
def test_get_footer_x(self):
|
||||
"""
|
||||
Test the footer_x getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to index 1
|
||||
page = AreaPositionPage()
|
||||
page.footer_x_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.footer_x
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_footer_x(self):
|
||||
"""
|
||||
Test the footer_x setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.footer_x = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.footer_x_spin_box.value() == 20
|
||||
|
||||
def test_get_footer_y(self):
|
||||
"""
|
||||
Test the footer_y getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indey 1
|
||||
page = AreaPositionPage()
|
||||
page.footer_y_spin_box.setValue(10)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.footer_y
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 10
|
||||
|
||||
def test_set_footer_y(self):
|
||||
"""
|
||||
Test the footer_y setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.footer_y = 20
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.footer_y_spin_box.value() == 20
|
||||
|
||||
def test_get_footer_width(self):
|
||||
"""
|
||||
Test the footer_width getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indewidth 1
|
||||
page = AreaPositionPage()
|
||||
page.footer_width_spin_box.setValue(1900)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.footer_width
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 1900
|
||||
|
||||
def test_set_footer_width(self):
|
||||
"""
|
||||
Test the footer_width setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.footer_width = 1900
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.footer_width_spin_box.value() == 1900
|
||||
|
||||
def test_get_footer_height(self):
|
||||
"""
|
||||
Test the footer_height getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to indeheight 1
|
||||
page = AreaPositionPage()
|
||||
page.footer_height_spin_box.setValue(1080)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.footer_height
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 1080
|
||||
|
||||
def test_set_footer_height(self):
|
||||
"""
|
||||
Test the footer_height setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.footer_height = 1080
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.footer_height_spin_box.value() == 1080
|
||||
|
||||
def test_get_use_footer_default_location(self):
|
||||
"""
|
||||
Test the use_footer_default_location getter
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance with the combobox set to index 1
|
||||
page = AreaPositionPage()
|
||||
page.footer_position_check_box.setChecked(False)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.use_footer_default_location
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_use_footer_default_location(self):
|
||||
"""
|
||||
Test the use_footer_default_location setter with an int
|
||||
"""
|
||||
# GIVEN: A AreaPositionPage instance
|
||||
page = AreaPositionPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.use_footer_default_location = True
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.footer_position_check_box.isChecked() is True
|
363
tests/openlp_core/pages/test_background.py
Normal file
363
tests/openlp_core/pages/test_background.py
Normal file
@ -0,0 +1,363 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.pages.background package.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
|
||||
from openlp.core.pages.background import BackgroundPage
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestBackgroundPage(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
def test_init_(self):
|
||||
"""
|
||||
Test the initialisation of BackgroundPage
|
||||
"""
|
||||
# GIVEN: The BackgroundPage class
|
||||
# WHEN: Initialising BackgroundPage
|
||||
# THEN: We should have an instance of the widget with no errors
|
||||
BackgroundPage()
|
||||
|
||||
def test_on_background_type_index_changed(self):
|
||||
"""
|
||||
Test the _on_background_type_index_changed() slot
|
||||
"""
|
||||
# GIVEN: And instance of BackgroundPage and some mock widgets
|
||||
page = BackgroundPage()
|
||||
page.color_widgets = [MagicMock()]
|
||||
page.gradient_widgets = [MagicMock()]
|
||||
|
||||
# WHEN: _on_background_type_index_changed
|
||||
page._on_background_type_index_changed(1)
|
||||
|
||||
# THEN: The correct widgets should be visible
|
||||
page.color_widgets[0].hide.assert_called_once()
|
||||
page.gradient_widgets[0].hide.assert_called_once()
|
||||
page.gradient_widgets[0].show.assert_called_once()
|
||||
|
||||
def test_get_background_type(self):
|
||||
"""
|
||||
Test the background_type getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the combobox set to index 1
|
||||
page = BackgroundPage()
|
||||
page.background_combo_box.setCurrentIndex(1)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.background_type
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 'gradient'
|
||||
|
||||
def test_set_background_type_int(self):
|
||||
"""
|
||||
Test the background_type setter with an int
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.background_type = BackgroundType.Image
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.background_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_background_type_str(self):
|
||||
"""
|
||||
Test the background_type setter with a str
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.background_type = BackgroundType.to_string(BackgroundType.Gradient)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.background_combo_box.currentIndex() == 1
|
||||
|
||||
def test_set_background_type_exception(self):
|
||||
"""
|
||||
Test the background_type setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='background_type must either be a string or an int'):
|
||||
page.background_type = []
|
||||
|
||||
def test_get_color(self):
|
||||
"""
|
||||
Test the color getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the color button set to #f0f
|
||||
page = BackgroundPage()
|
||||
page.color_button.color = '#f0f'
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.color
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == '#f0f'
|
||||
|
||||
def test_set_color(self):
|
||||
"""
|
||||
Test the color setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.color = '#0f0'
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.color_button.color == '#0f0'
|
||||
|
||||
def test_get_gradient_type(self):
|
||||
"""
|
||||
Test the gradient_type getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the combobox set to index 1
|
||||
page = BackgroundPage()
|
||||
page.gradient_combo_box.setCurrentIndex(1)
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.gradient_type
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == 'vertical'
|
||||
|
||||
def test_set_gradient_type_int(self):
|
||||
"""
|
||||
Test the gradient_type setter with an int
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.gradient_type = BackgroundGradientType.Horizontal
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.gradient_combo_box.currentIndex() == 0
|
||||
|
||||
def test_set_gradient_type_str(self):
|
||||
"""
|
||||
Test the gradient_type setter with a str
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.gradient_type = BackgroundGradientType.to_string(BackgroundGradientType.Circular)
|
||||
|
||||
# THEN: The combobox should be correct
|
||||
assert page.gradient_combo_box.currentIndex() == 2
|
||||
|
||||
def test_set_gradient_type_exception(self):
|
||||
"""
|
||||
Test the gradient_type setter with something other than a str or int
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
# THEN: An exception is raised
|
||||
with pytest.raises(TypeError, match='gradient_type must either be a string or an int'):
|
||||
page.gradient_type = []
|
||||
|
||||
def test_get_gradient_start(self):
|
||||
"""
|
||||
Test the gradient_start getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the gradient_start button set to #f0f
|
||||
page = BackgroundPage()
|
||||
page.gradient_start_button.color = '#f0f'
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.gradient_start
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == '#f0f'
|
||||
|
||||
def test_set_gradient_start(self):
|
||||
"""
|
||||
Test the gradient_start setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.gradient_start = '#0f0'
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.gradient_start_button.color == '#0f0'
|
||||
|
||||
def test_get_gradient_end(self):
|
||||
"""
|
||||
Test the gradient_end getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the gradient_end button set to #f0f
|
||||
page = BackgroundPage()
|
||||
page.gradient_end_button.color = '#f0f'
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.gradient_end
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == '#f0f'
|
||||
|
||||
def test_set_gradient_end(self):
|
||||
"""
|
||||
Test the gradient_end setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.gradient_end = '#0f0'
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.gradient_end_button.color == '#0f0'
|
||||
|
||||
def test_get_image_color(self):
|
||||
"""
|
||||
Test the image_color getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the image_color button set to #f0f
|
||||
page = BackgroundPage()
|
||||
page.image_color_button.color = '#f0f'
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.image_color
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == '#f0f'
|
||||
|
||||
def test_set_image_color(self):
|
||||
"""
|
||||
Test the image_color setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.image_color = '#0f0'
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.image_color_button.color == '#0f0'
|
||||
|
||||
def test_get_image_path(self):
|
||||
"""
|
||||
Test the image_path getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the image_path edit set to a path
|
||||
page = BackgroundPage()
|
||||
page.image_path_edit.path = Path('.')
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.image_path
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == Path('.')
|
||||
|
||||
def test_set_image_path(self):
|
||||
"""
|
||||
Test the image_path setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.image_path = Path('openlp')
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.image_path_edit.path == Path('openlp')
|
||||
|
||||
def test_get_video_color(self):
|
||||
"""
|
||||
Test the video_color getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the video_color button set to #f0f
|
||||
page = BackgroundPage()
|
||||
page.video_color_button.color = '#f0f'
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.video_color
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == '#f0f'
|
||||
|
||||
def test_set_video_color(self):
|
||||
"""
|
||||
Test the video_color setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.video_color = '#0f0'
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.video_color_button.color == '#0f0'
|
||||
|
||||
def test_get_video_path(self):
|
||||
"""
|
||||
Test the video_path getter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance with the video_path edit set to a path
|
||||
page = BackgroundPage()
|
||||
page.video_path_edit.path = Path('.')
|
||||
|
||||
# WHEN: The property is accessed
|
||||
result = page.video_path
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert result == Path('.')
|
||||
|
||||
def test_set_video_path(self):
|
||||
"""
|
||||
Test the video_path setter
|
||||
"""
|
||||
# GIVEN: A BackgroundPage instance
|
||||
page = BackgroundPage()
|
||||
|
||||
# WHEN: The property is set
|
||||
page.video_path = Path('openlp')
|
||||
|
||||
# THEN: The result should be correct
|
||||
assert page.video_path_edit.path == Path('openlp')
|
594
tests/openlp_core/pages/test_fontselection.py
Normal file
594
tests/openlp_core/pages/test_fontselection.py
Normal file
@ -0,0 +1,594 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.widgets.fontselect package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openlp.core.pages.fontselect import FontSelectPage
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestFontSelectPage(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
def test_init_(self):
|
||||
"""
|
||||
Test the initialisation of FontSelectPage
|
||||
"""
|
||||
# GIVEN: The FontSelectPage class
|
||||
# WHEN: Initialising FontSelectPage
|
||||
# THEN: We should have an instance of the widget with no errors
|
||||
FontSelectPage()
|
||||
|
||||
def test_font_name_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "font_name_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.font_name_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_font_name_changed('Sans serif')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_name_changed.emit.assert_called_once_with('Sans serif')
|
||||
|
||||
def test_font_name_changed_int(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "font_name_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.font_name_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_font_name_changed(5)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
assert instance.font_name_changed.emit.call_count == 0
|
||||
|
||||
def test_font_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "font_color_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.font_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font color changes
|
||||
instance._on_font_color_changed('#fff')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_color_changed.emit.assert_called_once_with('#fff')
|
||||
|
||||
def test_is_bold_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "is_bold_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.is_bold_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_style_bold_toggled(True)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_bold_changed.emit.assert_called_once_with(True)
|
||||
|
||||
def test_is_italic_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "style_italic_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.is_italic_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_style_italic_toggled(False)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_italic_changed.emit.assert_called_once_with(False)
|
||||
|
||||
def test_font_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "font_size_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.font_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font size changes
|
||||
instance._on_font_size_changed(14)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_size_changed.emit.assert_called_once_with(14)
|
||||
|
||||
def test_line_spacing_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "line_spacing_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.line_spacing_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_line_spacing_changed(1)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.line_spacing_changed.emit.assert_called_once_with(1)
|
||||
|
||||
def test_is_outline_enabled_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "outline_enabled_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.is_outline_enabled_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_toggled(True)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_outline_enabled_changed.emit.assert_called_once_with(True)
|
||||
|
||||
def test_outline_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "outline_color_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.outline_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_color_changed('#000')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.outline_color_changed.emit.assert_called_once_with('#000')
|
||||
|
||||
def test_outline_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "outline_size_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.outline_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_size_changed(2)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.outline_size_changed.emit.assert_called_once_with(2)
|
||||
|
||||
def test_is_shadow_enabled_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "is_shadow_enabled_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.is_shadow_enabled_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_toggled(False)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_shadow_enabled_changed.emit.assert_called_once_with(False)
|
||||
|
||||
def test_shadow_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "shadow_color_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_color_changed('#000')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.shadow_color_changed.emit.assert_called_once_with('#000')
|
||||
|
||||
def test_shadow_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectPage with a mocked out "shadow_size_changed" signal
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_size_changed(5)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.shadow_size_changed.emit.assert_called_once_with(5)
|
||||
|
||||
def test_enable_features(self):
|
||||
"""
|
||||
Test that the `enable_features` method correctly enables widgets based on features
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is enabled
|
||||
instance.enable_features('test')
|
||||
|
||||
# THEN: "show()" is called on all the widgets
|
||||
mock_label.show.assert_called_once()
|
||||
mock_control.show.assert_called_once()
|
||||
|
||||
def test_enable_missing_features(self):
|
||||
"""
|
||||
Test that the `enable_features` method correctly raises an error on a non-existent feature
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test1': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is enabled
|
||||
with pytest.raises(KeyError, match='No such feature'):
|
||||
instance.enable_features('test2')
|
||||
|
||||
def test_disable_features(self):
|
||||
"""
|
||||
Test that the `disable_features` method correctly disables widgets based on features
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is disabled
|
||||
instance.disable_features('test')
|
||||
|
||||
# THEN: "show()" is called on all the widgets
|
||||
mock_label.hide.assert_called_once()
|
||||
mock_control.hide.assert_called_once()
|
||||
|
||||
def test_disable_missing_features(self):
|
||||
"""
|
||||
Test that the `disable_features` method correctly raises an error on a non-existent feature
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test1': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is disabled
|
||||
with pytest.raises(KeyError, match='No such feature'):
|
||||
instance.disable_features('test2')
|
||||
|
||||
def test_get_font_name_property(self):
|
||||
"""
|
||||
Test the `font_name` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.font_name_combobox.currentFont = MagicMock(
|
||||
return_value=MagicMock(**{'family.return_value': 'Sans serif'}))
|
||||
|
||||
# WHEN: The `font_name` propert is accessed
|
||||
result = instance.font_name
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 'Sans serif'
|
||||
|
||||
def test_set_font_name_property(self):
|
||||
"""
|
||||
Test setting the `font_name` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.font_name_combobox.setCurrentFont = MagicMock()
|
||||
|
||||
# WHEN: The `font_name` property is set
|
||||
with patch('openlp.core.pages.fontselect.QtGui.QFont') as MockFont:
|
||||
mocked_font = MagicMock()
|
||||
MockFont.return_value = mocked_font
|
||||
instance.font_name = 'Serif'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
MockFont.assert_called_once_with('Serif')
|
||||
instance.font_name_combobox.setCurrentFont.assert_called_once_with(mocked_font)
|
||||
|
||||
def test_get_font_color_property(self):
|
||||
"""
|
||||
Test the `font_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.font_color_button.color = '#000'
|
||||
|
||||
# WHEN: The `font_color` propert is accessed
|
||||
result = instance.font_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#000'
|
||||
|
||||
def test_set_font_color_property(self):
|
||||
"""
|
||||
Test setting the `font_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
|
||||
# WHEN: The `font_color` property is set
|
||||
instance.font_color = '#fff'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
assert instance.font_color_button.color == '#fff'
|
||||
|
||||
def test_get_is_bold_property(self):
|
||||
"""
|
||||
Test the `is_bold` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.style_bold_button.isChecked = MagicMock(return_value=False)
|
||||
|
||||
# WHEN: The `is_bold` propert is accessed
|
||||
result = instance.is_bold
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_is_bold_property(self):
|
||||
"""
|
||||
Test setting the `is_bold` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.style_bold_button.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_bold` property is set
|
||||
instance.is_bold = True
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.style_bold_button.setChecked.assert_called_once_with(True)
|
||||
|
||||
def test_get_is_italic_property(self):
|
||||
"""
|
||||
Test the `is_italic` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.style_italic_button.isChecked = MagicMock(return_value=True)
|
||||
|
||||
# WHEN: The `is_italic` propert is accessed
|
||||
result = instance.is_italic
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is True
|
||||
|
||||
def test_set_is_italic_property(self):
|
||||
"""
|
||||
Test setting the `is_italic` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.style_italic_button.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_italic` property is set
|
||||
instance.is_italic = False
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.style_italic_button.setChecked.assert_called_once_with(False)
|
||||
|
||||
def test_get_font_size_property(self):
|
||||
"""
|
||||
Test the `font_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.font_size_spinbox.value = MagicMock(return_value=16)
|
||||
|
||||
# WHEN: The `font_size` propert is accessed
|
||||
result = instance.font_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 16
|
||||
|
||||
def test_set_font_size_property(self):
|
||||
"""
|
||||
Test setting the `font_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.font_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `font_size` property is set
|
||||
instance.font_size = 18
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.font_size_spinbox.setValue.assert_called_once_with(18)
|
||||
|
||||
def test_get_line_spacing_property(self):
|
||||
"""
|
||||
Test the `line_spacing` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.line_spacing_spinbox.value = MagicMock(return_value=1)
|
||||
|
||||
# WHEN: The `line_spacing` propert is accessed
|
||||
result = instance.line_spacing
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 1
|
||||
|
||||
def test_set_line_spacing_property(self):
|
||||
"""
|
||||
Test setting the `line_spacing` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.line_spacing_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `line_spacing` property is set
|
||||
instance.line_spacing = 2
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.line_spacing_spinbox.setValue.assert_called_once_with(2)
|
||||
|
||||
def test_get_is_outline_enabled_property(self):
|
||||
"""
|
||||
Test the `is_outline_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.outline_groupbox.isChecked = MagicMock(return_value=True)
|
||||
|
||||
# WHEN: The `is_outline_enabled` propert is accessed
|
||||
result = instance.is_outline_enabled
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is True
|
||||
|
||||
def test_set_is_outline_enabled_property(self):
|
||||
"""
|
||||
Test setting the `is_outline_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.outline_groupbox.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_outline_enabled` property is set
|
||||
instance.is_outline_enabled = False
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.outline_groupbox.setChecked.assert_called_once_with(False)
|
||||
|
||||
def test_get_outline_color_property(self):
|
||||
"""
|
||||
Test the `outline_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.outline_color_button.color = '#fff'
|
||||
|
||||
# WHEN: The `outline_color` propert is accessed
|
||||
result = instance.outline_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#fff'
|
||||
|
||||
def test_set_outline_color_property(self):
|
||||
"""
|
||||
Test setting the `outline_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
|
||||
# WHEN: The `outline_color` property is set
|
||||
instance.outline_color = '#000'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
assert instance.outline_color_button.color == '#000'
|
||||
|
||||
def test_get_outline_size_property(self):
|
||||
"""
|
||||
Test the `outline_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.outline_size_spinbox.value = MagicMock(return_value=2)
|
||||
|
||||
# WHEN: The `outline_size` propert is accessed
|
||||
result = instance.outline_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 2
|
||||
|
||||
def test_set_outline_size_property(self):
|
||||
"""
|
||||
Test setting the `outline_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.outline_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `outline_size` property is set
|
||||
instance.outline_size = 1
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.outline_size_spinbox.setValue.assert_called_once_with(1)
|
||||
|
||||
def test_get_is_shadow_enabled_property(self):
|
||||
"""
|
||||
Test the `is_shadow_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_groupbox.isChecked = MagicMock(return_value=False)
|
||||
|
||||
# WHEN: The `is_shadow_enabled` propert is accessed
|
||||
result = instance.is_shadow_enabled
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_is_shadow_enabled_property(self):
|
||||
"""
|
||||
Test setting the `is_shadow_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_groupbox.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_shadow_enabled` property is set
|
||||
instance.is_shadow_enabled = True
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_groupbox.setChecked.assert_called_once_with(True)
|
||||
|
||||
def test_get_shadow_color_property(self):
|
||||
"""
|
||||
Test the `shadow_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_color_button.color = '#000'
|
||||
|
||||
# WHEN: The `shadow_color` propert is accessed
|
||||
result = instance.shadow_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#000'
|
||||
|
||||
def test_set_shadow_color_property(self):
|
||||
"""
|
||||
Test setting the `shadow_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
|
||||
# WHEN: The `shadow_color` property is set
|
||||
instance.shadow_color = '#fff'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_color_button.color == '#fff'
|
||||
|
||||
def test_get_shadow_size_property(self):
|
||||
"""
|
||||
Test the `shadow_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_size_spinbox.value = MagicMock(return_value=5)
|
||||
|
||||
# WHEN: The `shadow_size` propert is accessed
|
||||
result = instance.shadow_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 5
|
||||
|
||||
def test_set_shadow_size_property(self):
|
||||
"""
|
||||
Test setting the `shadow_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectPage with some mocks
|
||||
instance = FontSelectPage()
|
||||
instance.shadow_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `shadow_size` property is set
|
||||
instance.shadow_size = 10
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_size_spinbox.setValue.assert_called_once_with(10)
|
97
tests/openlp_core/pages/test_gridlayoutpage.py
Normal file
97
tests/openlp_core/pages/test_gridlayoutpage.py
Normal file
@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Package to test the openlp.core.pages package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openlp.core.pages import GridLayoutPage
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestGridLayoutPage(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
@patch('openlp.core.pages.GridLayoutPage.setup_ui')
|
||||
@patch('openlp.core.pages.GridLayoutPage.retranslate_ui')
|
||||
def test_resize_event(self, mocked_retranslate_ui, mocked_setup_ui):
|
||||
"""
|
||||
Test that the `resizeEvent()` method called the `resize_columns()` method.
|
||||
"""
|
||||
# GIVEN: An instance of GridLayoutPage with a mocked out "resize_columns" method
|
||||
instance = GridLayoutPage()
|
||||
instance.resize_columns = MagicMock()
|
||||
|
||||
# WHEN: resizeEvent is called
|
||||
instance.resizeEvent(None)
|
||||
|
||||
# THEN: resize_widgets should have been called
|
||||
instance.resize_columns.assert_called_once()
|
||||
|
||||
def test_unimplemented_setup_ui(self):
|
||||
"""
|
||||
Test that setup_ui() throws a NotImplementedError
|
||||
"""
|
||||
with pytest.raises(NotImplementedError, match='Descendant pages need to implement setup_ui'):
|
||||
GridLayoutPage()
|
||||
|
||||
@patch('openlp.core.pages.GridLayoutPage.setup_ui')
|
||||
def test_unimplemented_retranslate_ui(self, mocked_setup_ui):
|
||||
"""
|
||||
Test that retranslate_ui() throws a NotImplementedError
|
||||
"""
|
||||
with pytest.raises(NotImplementedError, match='Descendant pages need to implement retranslate_ui'):
|
||||
GridLayoutPage()
|
||||
|
||||
@patch('openlp.core.pages.GridLayoutPage.setup_ui')
|
||||
@patch('openlp.core.pages.GridLayoutPage.retranslate_ui')
|
||||
def test_resize_columns(self, mocked_retranslate_ui, mocked_setup_ui):
|
||||
"""
|
||||
Test the `resize_columns()` method with an implemented page
|
||||
"""
|
||||
# GIVEN: An instance of GridLayoutPage and various mocked out methods
|
||||
instance = GridLayoutPage()
|
||||
instance.layout.contentsRect = MagicMock(return_value=MagicMock(**{'width.return_value': 100}))
|
||||
instance.layout.horizontalSpacing = MagicMock(return_value=6)
|
||||
instance.layout.columnCount = MagicMock(return_value=4)
|
||||
instance.layout.setColumnMinimumWidth = MagicMock()
|
||||
|
||||
# WHEN: `resize_columns()` is called
|
||||
instance.resize_columns()
|
||||
|
||||
# THEN: The column widths should be set to 16
|
||||
instance.layout.contentsRect.assert_called_once()
|
||||
instance.layout.horizontalSpacing.assert_called_once()
|
||||
instance.layout.columnCount.assert_called_once()
|
||||
assert instance._column_width == 20
|
||||
assert instance.layout.setColumnMinimumWidth.call_args_list == [call(0, 20), call(1, 20),
|
||||
call(2, 20), call(3, 20)]
|
@ -19,19 +19,22 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
Interface tests to test the ThemeWizard class and related methods.
|
||||
Test the ThemeForm class and related methods.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib.theme import BackgroundType
|
||||
from openlp.core.ui.themeform import ThemeForm
|
||||
from openlp.core.ui.themelayoutform import ThemeLayoutForm
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestThemeManager(TestCase, TestMixin):
|
||||
class TestThemeForm(TestCase, TestMixin):
|
||||
"""
|
||||
Test the functions in the ThemeManager module
|
||||
Test the functions in the ThemeForm Class
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
@ -41,8 +44,8 @@ class TestThemeManager(TestCase, TestMixin):
|
||||
mocked_renderer = MagicMock()
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
|
||||
@patch('openlp.core.display.window.QtWidgets.QVBoxLayout')
|
||||
def test_create_theme_wizard(self, mocked_qvboxlayout):
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_create_theme_wizard(self, mocked_setup):
|
||||
"""
|
||||
Test creating a ThemeForm instance
|
||||
"""
|
||||
@ -50,3 +53,358 @@ class TestThemeManager(TestCase, TestMixin):
|
||||
# WHEN: An object is created
|
||||
# THEN: There should be no problems
|
||||
ThemeForm(None)
|
||||
|
||||
def test_setup(self):
|
||||
"""
|
||||
Test the _setup method
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance
|
||||
with patch('openlp.core.ui.themeform.ThemeForm._setup'):
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.setup_ui = MagicMock()
|
||||
theme_form.main_area_page = MagicMock()
|
||||
theme_form.footer_area_page = MagicMock()
|
||||
|
||||
# WHEN: _setup() is called
|
||||
theme_form._setup()
|
||||
|
||||
# THEN: The right calls should have been made
|
||||
theme_form.setup_ui.assert_called_once_with(theme_form)
|
||||
assert theme_form.can_update_theme is True
|
||||
assert theme_form.temp_background_filename is None
|
||||
assert isinstance(theme_form.theme_layout_form, ThemeLayoutForm)
|
||||
theme_form.main_area_page.font_name_changed.connect.assert_called_once_with(theme_form.calculate_lines)
|
||||
theme_form.main_area_page.font_size_changed.connect.assert_called_once_with(theme_form.calculate_lines)
|
||||
theme_form.main_area_page.line_spacing_changed.connect.assert_called_once_with(theme_form.calculate_lines)
|
||||
theme_form.main_area_page.is_outline_enabled_changed.connect.assert_called_once_with(
|
||||
theme_form.on_outline_toggled)
|
||||
theme_form.main_area_page.outline_size_changed.connect.assert_called_once_with(theme_form.calculate_lines)
|
||||
theme_form.main_area_page.is_shadow_enabled_changed.connect.assert_called_once_with(
|
||||
theme_form.on_shadow_toggled)
|
||||
theme_form.main_area_page.shadow_size_changed.connect.assert_called_once_with(theme_form.calculate_lines)
|
||||
theme_form.footer_area_page.font_name_changed.connect.assert_called_once_with(theme_form.update_theme)
|
||||
theme_form.footer_area_page.font_size_changed.connect.assert_called_once_with(theme_form.update_theme)
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_set_defaults(self, mocked_setup):
|
||||
"""
|
||||
Test that the right methods are called by the set_defaults() method
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance with mocked methods
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.restart = MagicMock()
|
||||
theme_form.set_background_page_values = MagicMock()
|
||||
theme_form.set_main_area_page_values = MagicMock()
|
||||
theme_form.set_footer_area_page_values = MagicMock()
|
||||
theme_form.set_alignment_page_values = MagicMock()
|
||||
theme_form.set_position_page_values = MagicMock()
|
||||
theme_form.set_preview_page_values = MagicMock()
|
||||
|
||||
# WHEN: set_defaults() is called
|
||||
theme_form.set_defaults()
|
||||
|
||||
# THEN: all the mocks are called
|
||||
theme_form.restart.assert_called_once()
|
||||
theme_form.set_background_page_values.assert_called_once()
|
||||
theme_form.set_main_area_page_values.assert_called_once()
|
||||
theme_form.set_footer_area_page_values.assert_called_once()
|
||||
theme_form.set_alignment_page_values.assert_called_once()
|
||||
theme_form.set_position_page_values.assert_called_once()
|
||||
theme_form.set_preview_page_values.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_calculate_lines(self, mocked_setup):
|
||||
"""
|
||||
Test the calculate_lines() method
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance with some mocked methods
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.theme = None
|
||||
theme_form.welcome_page = None
|
||||
theme_form.currentPage = MagicMock()
|
||||
theme_form.update_theme = MagicMock()
|
||||
mocked_theme_manager = MagicMock()
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
|
||||
# WHEN: calculate_lines() is called
|
||||
theme_form.calculate_lines()
|
||||
|
||||
# THEN: The mocks should have been called correctly
|
||||
theme_form.currentPage.assert_called_once()
|
||||
theme_form.update_theme.assert_called_once()
|
||||
mocked_theme_manager.generate_image.assert_called_once_with(None, True)
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_update_lines_text(self, mocked_setup):
|
||||
"""
|
||||
Test the update_lines_text() method
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance with some mocked methods
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.main_line_count_label = MagicMock()
|
||||
|
||||
# WHEN: calculate_lines() is called
|
||||
theme_form.update_lines_text(10)
|
||||
|
||||
# THEN: The mocks should have been called correctly
|
||||
theme_form.main_line_count_label.setText.assert_called_once_with('(approximately 10 lines per slide)')
|
||||
|
||||
@patch('openlp.core.ui.themeform.QtWidgets.QWizard.resizeEvent')
|
||||
@patch('openlp.core.ui.themeform.QtGui.QResizeEvent')
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_resize_event(self, mocked_setup, MockResizeEvent, mocked_resizeEvent):
|
||||
"""
|
||||
Test that the resizeEvent method handles resizing correctly
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance with a number of mocked methods
|
||||
mocked_event = MagicMock()
|
||||
MockResizeEvent.return_value = mocked_event
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.size = MagicMock(return_value=1920)
|
||||
theme_form.preview_area_layout = MagicMock()
|
||||
theme_form.preview_box = MagicMock(**{'width.return_value': 300})
|
||||
mocked_renderer = MagicMock(**{'width.return_value': 1920, 'height.return_value': 1080})
|
||||
Registry().remove('renderer')
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
|
||||
# WHEN: resizeEvent() is called
|
||||
theme_form.resizeEvent()
|
||||
|
||||
# THEN: The correct calls should have been made
|
||||
MockResizeEvent.assert_called_once_with(1920, 1920)
|
||||
mocked_resizeEvent.assert_called_once_with(theme_form, mocked_event)
|
||||
assert mocked_renderer.width.call_count == 2
|
||||
mocked_renderer.height.assert_called_once()
|
||||
theme_form.preview_area_layout.set_aspect_ratio.assert_called_once_with(16 / 9)
|
||||
theme_form.preview_box.set_scale.assert_called_once_with(float(300 / 1920))
|
||||
|
||||
@patch('openlp.core.ui.themeform.QtWidgets.QWizard.resizeEvent')
|
||||
@patch('openlp.core.ui.themeform.QtGui.QResizeEvent')
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_resize_event_dbze(self, mocked_setup, MockResizeEvent, mocked_resizeEvent):
|
||||
"""
|
||||
Test that the resizeEvent method handles a divide by zero exception correctly
|
||||
"""
|
||||
# GIVEN: A ThemeForm instance with a number of mocked methods
|
||||
mocked_event = MagicMock()
|
||||
MockResizeEvent.return_value = mocked_event
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.size = MagicMock(return_value=1920)
|
||||
theme_form.preview_area_layout = MagicMock()
|
||||
theme_form.preview_box = MagicMock(**{'width.return_value': 300})
|
||||
mocked_renderer = MagicMock(**{'width.return_value': 1920, 'height.return_value': 0})
|
||||
Registry().remove('renderer')
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
|
||||
# WHEN: resizeEvent() is called
|
||||
theme_form.resizeEvent()
|
||||
|
||||
# THEN: The correct calls should have been made
|
||||
MockResizeEvent.assert_called_once_with(1920, 1920)
|
||||
mocked_resizeEvent.assert_called_once_with(theme_form, mocked_event)
|
||||
assert mocked_renderer.width.call_count == 2
|
||||
mocked_renderer.height.assert_called_once()
|
||||
theme_form.preview_area_layout.set_aspect_ratio.assert_called_once_with(1)
|
||||
theme_form.preview_box.set_scale.assert_called_once_with(float(300 / 1920))
|
||||
|
||||
@patch('openlp.core.ui.themeform.QtWidgets.QMessageBox.critical')
|
||||
@patch('openlp.core.ui.themeform.is_not_image_file')
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_validate_current_page_with_image(self, mocked_setup, mocked_is_not_image_file, mocked_critical):
|
||||
"""
|
||||
Test the validateCurrentPage() method
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock(background_type=BackgroundType.to_string(BackgroundType.Image),
|
||||
image_path=Path('picture.jpg'))
|
||||
theme_form.page = MagicMock(return_value=theme_form.background_page)
|
||||
mocked_is_not_image_file.return_value = True
|
||||
|
||||
# WHEN: validateCurrentPage() is called
|
||||
result = theme_form.validateCurrentPage()
|
||||
|
||||
# THEN: The right methods were called, and the result is False
|
||||
mocked_critical.assert_called_once_with(theme_form, 'Background Image Empty',
|
||||
'You have not selected a background image. '
|
||||
'Please select one before continuing.')
|
||||
assert result is False
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_validate_current_page(self, mocked_setup):
|
||||
"""
|
||||
Test the validateCurrentPage() method
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.page = MagicMock()
|
||||
|
||||
# WHEN: validateCurrentPage() is called
|
||||
result = theme_form.validateCurrentPage()
|
||||
|
||||
# THEN: The right methods were called, and the result is False
|
||||
assert result is True
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_on_current_id_changed_preview(self, mocked_setup):
|
||||
"""
|
||||
Test the on_current_id_changed() method
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.theme = 'my fake theme'
|
||||
theme_form.area_position_page = MagicMock()
|
||||
theme_form.preview_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.preview_page)
|
||||
theme_form.update_theme = MagicMock()
|
||||
theme_form.preview_box = MagicMock(**{'width.return_value': 300})
|
||||
theme_form.preview_area_layout = MagicMock()
|
||||
theme_form.resizeEvent = MagicMock()
|
||||
mocked_renderer = MagicMock(**{'width.return_value': 1920, 'height.return_value': 0})
|
||||
Registry().remove('renderer')
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
|
||||
# WHEN: on_current_id_changed() is called
|
||||
theme_form.on_current_id_changed(1)
|
||||
|
||||
# THEN: The right options should have been set
|
||||
theme_form.update_theme.assert_called_once()
|
||||
theme_form.preview_box.set_theme.assert_called_once_with('my fake theme')
|
||||
theme_form.preview_box.clear_slides.assert_called_once()
|
||||
theme_form.preview_box.set_scale.assert_called_once_with(float(300 / 1920))
|
||||
theme_form.preview_area_layout.set_aspect_ratio(16 / 9)
|
||||
theme_form.resizeEvent.assert_called_once()
|
||||
theme_form.preview_box.show.assert_called_once()
|
||||
theme_form.preview_box.generate_preview.assert_called_once_with('my fake theme', False, False)
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_on_outline_toggled(self, mocked_setup):
|
||||
"""
|
||||
Test the on_outline_toggled() method
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.can_update_theme = True
|
||||
theme_form.theme = MagicMock()
|
||||
theme_form.calculate_lines = MagicMock()
|
||||
|
||||
# WHEN: on_outline_toggled is called
|
||||
theme_form.on_outline_toggled(True)
|
||||
|
||||
# THEN: Everything is working right
|
||||
assert theme_form.theme.font_main_outline is True
|
||||
theme_form.calculate_lines.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_on_shadow_toggled(self, mocked_setup):
|
||||
"""
|
||||
Test the on_shadow_toggled() method
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.can_update_theme = True
|
||||
theme_form.theme = MagicMock()
|
||||
theme_form.calculate_lines = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.on_shadow_toggled(True)
|
||||
|
||||
# THEN: Everything is working right
|
||||
assert theme_form.theme.font_main_shadow is True
|
||||
theme_form.calculate_lines.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_initialise_page_background(self, mocked_setup):
|
||||
"""
|
||||
Test the initializePage() method with the background page
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.background_page)
|
||||
theme_form.set_background_page_values = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.initializePage(0)
|
||||
|
||||
# THEN: Everything is working right
|
||||
theme_form.set_background_page_values.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_initialise_page_main_area(self, mocked_setup):
|
||||
"""
|
||||
Test the initializePage() method with the main_area page
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.main_area_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.main_area_page)
|
||||
theme_form.set_main_area_page_values = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.initializePage(0)
|
||||
|
||||
# THEN: Everything is working right
|
||||
theme_form.set_main_area_page_values.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_initialise_page_footer_area(self, mocked_setup):
|
||||
"""
|
||||
Test the initializePage() method with the footer_area page
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.main_area_page = MagicMock()
|
||||
theme_form.footer_area_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.footer_area_page)
|
||||
theme_form.set_footer_area_page_values = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.initializePage(0)
|
||||
|
||||
# THEN: Everything is working right
|
||||
theme_form.set_footer_area_page_values.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_initialise_page_alignment(self, mocked_setup):
|
||||
"""
|
||||
Test the initializePage() method with the alignment page
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.main_area_page = MagicMock()
|
||||
theme_form.footer_area_page = MagicMock()
|
||||
theme_form.alignment_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.alignment_page)
|
||||
theme_form.set_alignment_page_values = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.initializePage(0)
|
||||
|
||||
# THEN: Everything is working right
|
||||
theme_form.set_alignment_page_values.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.themeform.ThemeForm._setup')
|
||||
def test_initialise_page_area_position(self, mocked_setup):
|
||||
"""
|
||||
Test the initializePage() method with the area_position page
|
||||
"""
|
||||
# GIVEN: An instance of ThemeForm with some mocks
|
||||
theme_form = ThemeForm(None)
|
||||
theme_form.background_page = MagicMock()
|
||||
theme_form.main_area_page = MagicMock()
|
||||
theme_form.footer_area_page = MagicMock()
|
||||
theme_form.alignment_page = MagicMock()
|
||||
theme_form.area_position_page = MagicMock()
|
||||
theme_form.page = MagicMock(return_value=theme_form.area_position_page)
|
||||
theme_form.set_position_page_values = MagicMock()
|
||||
|
||||
# WHEN: on_shadow_toggled is called
|
||||
theme_form.initializePage(0)
|
||||
|
||||
# THEN: Everything is working right
|
||||
theme_form.set_position_page_values.assert_called_once()
|
||||
|
@ -24,12 +24,11 @@ Package to test the openlp.core.widgets.widgets package.
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
import pytest
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.settings import ProxyMode
|
||||
from openlp.core.display.screens import Screen
|
||||
from openlp.core.widgets.widgets import ProxyWidget, ProxyDialog, ScreenButton, ScreenSelectionWidget, FontSelectWidget
|
||||
from openlp.core.widgets.widgets import ProxyWidget, ProxyDialog, ScreenButton, ScreenSelectionWidget
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
@ -526,604 +525,3 @@ class TestScreenSelectionWidget(TestCase, TestMixin):
|
||||
'checkbox for that screen.', parent=instance, question=False)
|
||||
assert instance.use_screen_check_box.isChecked() is True
|
||||
assert instance.display_group_box.isChecked() is True
|
||||
|
||||
|
||||
class TestFontSelectWidget(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
"""Test setup"""
|
||||
self.setup_application()
|
||||
self.build_settings()
|
||||
|
||||
def tearDown(self):
|
||||
"""Tear down tests"""
|
||||
del self.app
|
||||
|
||||
def test_init_(self):
|
||||
"""
|
||||
Test the initialisation of FontSelectWidget
|
||||
"""
|
||||
# GIVEN: The FontSelectWidget class
|
||||
# WHEN: Initialising FontSelectWidget
|
||||
# THEN: We should have an instance of the widget with no errors
|
||||
FontSelectWidget()
|
||||
|
||||
def test_resize_event(self):
|
||||
"""
|
||||
Test that the `resizeEvent()` method called the `resize_widgets()` method.
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "resize_widgets" method
|
||||
instance = FontSelectWidget()
|
||||
instance.resize_widgets = MagicMock()
|
||||
|
||||
# WHEN: resizeEvent is called
|
||||
instance.resizeEvent(None)
|
||||
|
||||
# THEN: resize_widgets should have been called
|
||||
instance.resize_widgets.assert_called_once()
|
||||
|
||||
def test_font_name_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "font_name_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.font_name_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_font_name_changed('Sans serif')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_name_changed.emit.assert_called_once_with('Sans serif')
|
||||
|
||||
def test_font_name_changed_int(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "font_name_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.font_name_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_font_name_changed(5)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
assert instance.font_name_changed.emit.call_count == 0
|
||||
|
||||
def test_font_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "font_color_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.font_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font color changes
|
||||
instance._on_font_color_changed('#fff')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_color_changed.emit.assert_called_once_with('#fff')
|
||||
|
||||
def test_is_bold_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "is_bold_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.is_bold_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_style_bold_toggled(True)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_bold_changed.emit.assert_called_once_with(True)
|
||||
|
||||
def test_is_italic_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "style_italic_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.is_italic_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_style_italic_toggled(False)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_italic_changed.emit.assert_called_once_with(False)
|
||||
|
||||
def test_font_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "font_size_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.font_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font size changes
|
||||
instance._on_font_size_changed(14)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.font_size_changed.emit.assert_called_once_with(14)
|
||||
|
||||
def test_line_spacing_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "line_spacing_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.line_spacing_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_line_spacing_changed(1)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.line_spacing_changed.emit.assert_called_once_with(1)
|
||||
|
||||
def test_is_outline_enabled_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "outline_enabled_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.is_outline_enabled_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_toggled(True)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_outline_enabled_changed.emit.assert_called_once_with(True)
|
||||
|
||||
def test_outline_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "outline_color_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_color_changed('#000')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.outline_color_changed.emit.assert_called_once_with('#000')
|
||||
|
||||
def test_outline_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "outline_size_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_outline_size_changed(2)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.outline_size_changed.emit.assert_called_once_with(2)
|
||||
|
||||
def test_is_shadow_enabled_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "is_shadow_enabled_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.is_shadow_enabled_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_toggled(False)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.is_shadow_enabled_changed.emit.assert_called_once_with(False)
|
||||
|
||||
def test_shadow_color_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "shadow_color_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_color_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_color_changed('#000')
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.shadow_color_changed.emit.assert_called_once_with('#000')
|
||||
|
||||
def test_shadow_size_changed(self):
|
||||
# GIVEN: An instance of FontSelectWidget with a mocked out "shadow_size_changed" signal
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_size_changed = MagicMock()
|
||||
|
||||
# WHEN: The font name changes
|
||||
instance._on_shadow_size_changed(5)
|
||||
|
||||
# THEN: The signal should be emitted with the correct value
|
||||
instance.shadow_size_changed.emit.assert_called_once_with(5)
|
||||
|
||||
def test_resize_widgets(self):
|
||||
"""
|
||||
Test the `resize_widgets()` method
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget and various mocked out methods
|
||||
instance = FontSelectWidget()
|
||||
instance.geometry = MagicMock(return_value=MagicMock(**{'width.return_value': 100}))
|
||||
instance.layout.contentsMargins = MagicMock(return_value=MagicMock(**{'left.return_value': 8,
|
||||
'right.return_value': 8}))
|
||||
instance.layout.horizontalSpacing = MagicMock(return_value=6)
|
||||
instance.layout.setColumnMinimumWidth = MagicMock()
|
||||
|
||||
# WHEN: `resize_widgets()` is called
|
||||
instance.resize_widgets()
|
||||
|
||||
# THEN: The column widths should be set to 16
|
||||
instance.geometry.assert_called_once()
|
||||
instance.layout.contentsMargins.assert_called_once()
|
||||
instance.layout.horizontalSpacing.assert_called_once()
|
||||
assert instance._column_width == 16
|
||||
assert instance.layout.setColumnMinimumWidth.call_args_list == [call(0, 16), call(1, 16),
|
||||
call(2, 16), call(3, 16)]
|
||||
|
||||
def test_enable_features(self):
|
||||
"""
|
||||
Test that the `enable_features` method correctly enables widgets based on features
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is enabled
|
||||
instance.enable_features('test')
|
||||
|
||||
# THEN: "show()" is called on all the widgets
|
||||
mock_label.show.assert_called_once()
|
||||
mock_control.show.assert_called_once()
|
||||
|
||||
def test_enable_missing_features(self):
|
||||
"""
|
||||
Test that the `enable_features` method correctly raises an error on a non-existent feature
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test1': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is enabled
|
||||
with pytest.raises(KeyError, match='No such feature'):
|
||||
instance.enable_features('test2')
|
||||
|
||||
def test_disable_features(self):
|
||||
"""
|
||||
Test that the `disable_features` method correctly disables widgets based on features
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is disabled
|
||||
instance.disable_features('test')
|
||||
|
||||
# THEN: "show()" is called on all the widgets
|
||||
mock_label.hide.assert_called_once()
|
||||
mock_control.hide.assert_called_once()
|
||||
|
||||
def test_disable_missing_features(self):
|
||||
"""
|
||||
Test that the `disable_features` method correctly raises an error on a non-existent feature
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
mock_label = MagicMock()
|
||||
mock_control = MagicMock()
|
||||
instance.feature_widgets = {'test1': [mock_label, mock_control]}
|
||||
|
||||
# WHEN: The "test" feature is disabled
|
||||
with pytest.raises(KeyError, match='No such feature'):
|
||||
instance.disable_features('test2')
|
||||
|
||||
def test_get_font_name_property(self):
|
||||
"""
|
||||
Test the `font_name` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.font_name_combobox.currentFont = MagicMock(
|
||||
return_value=MagicMock(**{'family.return_value': 'Sans serif'}))
|
||||
|
||||
# WHEN: The `font_name` propert is accessed
|
||||
result = instance.font_name
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 'Sans serif'
|
||||
|
||||
def test_set_font_name_property(self):
|
||||
"""
|
||||
Test setting the `font_name` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.font_name_combobox.setCurrentFont = MagicMock()
|
||||
|
||||
# WHEN: The `font_name` property is set
|
||||
with patch('openlp.core.widgets.widgets.QtGui.QFont') as MockFont:
|
||||
mocked_font = MagicMock()
|
||||
MockFont.return_value = mocked_font
|
||||
instance.font_name = 'Serif'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
MockFont.assert_called_once_with('Serif')
|
||||
instance.font_name_combobox.setCurrentFont.assert_called_once_with(mocked_font)
|
||||
|
||||
def test_get_font_color_property(self):
|
||||
"""
|
||||
Test the `font_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.font_color_button.color = '#000'
|
||||
|
||||
# WHEN: The `font_color` propert is accessed
|
||||
result = instance.font_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#000'
|
||||
|
||||
def test_set_font_color_property(self):
|
||||
"""
|
||||
Test setting the `font_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
|
||||
# WHEN: The `font_color` property is set
|
||||
instance.font_color = '#fff'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
assert instance.font_color_button.color == '#fff'
|
||||
|
||||
def test_get_is_bold_property(self):
|
||||
"""
|
||||
Test the `is_bold` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.style_bold_button.isChecked = MagicMock(return_value=False)
|
||||
|
||||
# WHEN: The `is_bold` propert is accessed
|
||||
result = instance.is_bold
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_is_bold_property(self):
|
||||
"""
|
||||
Test setting the `is_bold` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.style_bold_button.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_bold` property is set
|
||||
instance.is_bold = True
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.style_bold_button.setChecked.assert_called_once_with(True)
|
||||
|
||||
def test_get_is_italic_property(self):
|
||||
"""
|
||||
Test the `is_italic` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.style_italic_button.isChecked = MagicMock(return_value=True)
|
||||
|
||||
# WHEN: The `is_italic` propert is accessed
|
||||
result = instance.is_italic
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is True
|
||||
|
||||
def test_set_is_italic_property(self):
|
||||
"""
|
||||
Test setting the `is_italic` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.style_italic_button.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_italic` property is set
|
||||
instance.is_italic = False
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.style_italic_button.setChecked.assert_called_once_with(False)
|
||||
|
||||
def test_get_font_size_property(self):
|
||||
"""
|
||||
Test the `font_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.font_size_spinbox.value = MagicMock(return_value=16)
|
||||
|
||||
# WHEN: The `font_size` propert is accessed
|
||||
result = instance.font_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 16
|
||||
|
||||
def test_set_font_size_property(self):
|
||||
"""
|
||||
Test setting the `font_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.font_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `font_size` property is set
|
||||
instance.font_size = 18
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.font_size_spinbox.setValue.assert_called_once_with(18)
|
||||
|
||||
def test_get_line_spacing_property(self):
|
||||
"""
|
||||
Test the `line_spacing` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.line_spacing_spinbox.value = MagicMock(return_value=1)
|
||||
|
||||
# WHEN: The `line_spacing` propert is accessed
|
||||
result = instance.line_spacing
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 1
|
||||
|
||||
def test_set_line_spacing_property(self):
|
||||
"""
|
||||
Test setting the `line_spacing` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.line_spacing_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `line_spacing` property is set
|
||||
instance.line_spacing = 2
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.line_spacing_spinbox.setValue.assert_called_once_with(2)
|
||||
|
||||
def test_get_is_outline_enabled_property(self):
|
||||
"""
|
||||
Test the `is_outline_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_groupbox.isChecked = MagicMock(return_value=True)
|
||||
|
||||
# WHEN: The `is_outline_enabled` propert is accessed
|
||||
result = instance.is_outline_enabled
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is True
|
||||
|
||||
def test_set_is_outline_enabled_property(self):
|
||||
"""
|
||||
Test setting the `is_outline_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_groupbox.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_outline_enabled` property is set
|
||||
instance.is_outline_enabled = False
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.outline_groupbox.setChecked.assert_called_once_with(False)
|
||||
|
||||
def test_get_outline_color_property(self):
|
||||
"""
|
||||
Test the `outline_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_color_button.color = '#fff'
|
||||
|
||||
# WHEN: The `outline_color` propert is accessed
|
||||
result = instance.outline_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#fff'
|
||||
|
||||
def test_set_outline_color_property(self):
|
||||
"""
|
||||
Test setting the `outline_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
|
||||
# WHEN: The `outline_color` property is set
|
||||
instance.outline_color = '#000'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
assert instance.outline_color_button.color == '#000'
|
||||
|
||||
def test_get_outline_size_property(self):
|
||||
"""
|
||||
Test the `outline_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_size_spinbox.value = MagicMock(return_value=2)
|
||||
|
||||
# WHEN: The `outline_size` propert is accessed
|
||||
result = instance.outline_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 2
|
||||
|
||||
def test_set_outline_size_property(self):
|
||||
"""
|
||||
Test setting the `outline_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.outline_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `outline_size` property is set
|
||||
instance.outline_size = 1
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.outline_size_spinbox.setValue.assert_called_once_with(1)
|
||||
|
||||
def test_get_is_shadow_enabled_property(self):
|
||||
"""
|
||||
Test the `is_shadow_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_groupbox.isChecked = MagicMock(return_value=False)
|
||||
|
||||
# WHEN: The `is_shadow_enabled` propert is accessed
|
||||
result = instance.is_shadow_enabled
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result is False
|
||||
|
||||
def test_set_is_shadow_enabled_property(self):
|
||||
"""
|
||||
Test setting the `is_shadow_enabled` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_groupbox.setChecked = MagicMock()
|
||||
|
||||
# WHEN: The `is_shadow_enabled` property is set
|
||||
instance.is_shadow_enabled = True
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_groupbox.setChecked.assert_called_once_with(True)
|
||||
|
||||
def test_get_shadow_color_property(self):
|
||||
"""
|
||||
Test the `shadow_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_color_button.color = '#000'
|
||||
|
||||
# WHEN: The `shadow_color` propert is accessed
|
||||
result = instance.shadow_color
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == '#000'
|
||||
|
||||
def test_set_shadow_color_property(self):
|
||||
"""
|
||||
Test setting the `shadow_color` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
|
||||
# WHEN: The `shadow_color` property is set
|
||||
instance.shadow_color = '#fff'
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_color_button.color == '#fff'
|
||||
|
||||
def test_get_shadow_size_property(self):
|
||||
"""
|
||||
Test the `shadow_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_size_spinbox.value = MagicMock(return_value=5)
|
||||
|
||||
# WHEN: The `shadow_size` propert is accessed
|
||||
result = instance.shadow_size
|
||||
|
||||
# THEN: The value should be correct
|
||||
assert result == 5
|
||||
|
||||
def test_set_shadow_size_property(self):
|
||||
"""
|
||||
Test setting the `shadow_size` property
|
||||
"""
|
||||
# GIVEN: An instance of FontSelectWidget with some mocks
|
||||
instance = FontSelectWidget()
|
||||
instance.shadow_size_spinbox.setValue = MagicMock()
|
||||
|
||||
# WHEN: The `shadow_size` property is set
|
||||
instance.shadow_size = 10
|
||||
|
||||
# THEN: The correct value should be set
|
||||
instance.shadow_size_spinbox.setValue.assert_called_once_with(10)
|
||||
|
Loading…
Reference in New Issue
Block a user