openlp/openlp/core/pages/background.py

351 lines
17 KiB
Python

# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2022 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.lib.ui import critical_error_message_box
from openlp.core.pages import GridLayoutPage
from openlp.core.ui.icons import UiIcons
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
from openlp.core.ui.media.vlcplayer import get_vlc
if get_vlc() is not None:
from openlp.plugins.media.forms.streamselectorform import StreamSelectorForm
from openlp.plugins.media.forms.networkstreamselectorform import NetworkStreamSelectorForm
class BackgroundPage(GridLayoutPage):
"""
A background selection widget
"""
Color = 'color'
Gradient = 'gradient'
Image = 'image'
Video = 'video'
Stream = 'stream'
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]
# streams
self.stream_label = FormLabel(self)
self.stream_label.setObjectName('stream_label')
self.layout.addWidget(self.stream_label, 6, 0)
self.stream_layout = QtWidgets.QHBoxLayout()
self.stream_lineedit = QtWidgets.QLineEdit(self)
self.stream_lineedit.setObjectName('stream_lineedit')
self.stream_lineedit.setReadOnly(True)
self.stream_layout.addWidget(self.stream_lineedit)
# button to open select device stream form
self.device_stream_select_button = QtWidgets.QToolButton(self)
self.device_stream_select_button.setObjectName('device_stream_select_button')
self.device_stream_select_button.setIcon(UiIcons().device_stream)
self.stream_layout.addWidget(self.device_stream_select_button)
# button to open select network stream form
self.network_stream_select_button = QtWidgets.QToolButton(self)
self.network_stream_select_button.setObjectName('network_stream_select_button')
self.network_stream_select_button.setIcon(UiIcons().network_stream)
self.stream_layout.addWidget(self.network_stream_select_button)
self.layout.addLayout(self.stream_layout, 6, 1, 1, 3)
self.stream_color_label = FormLabel(self)
self.stream_color_label.setObjectName('stream_color_label')
self.layout.addWidget(self.stream_color_label, 7, 0)
self.stream_color_button = ColorButton(self)
self.stream_color_button.color = '#000000'
self.stream_color_button.setObjectName('stream_color_button')
self.layout.addWidget(self.stream_color_button, 7, 1)
self.stream_widgets = [self.stream_label, self.stream_lineedit, self.device_stream_select_button,
self.network_stream_select_button, self.stream_color_label, self.stream_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)
self.device_stream_select_button.clicked.connect(self._on_device_stream_select_button_triggered)
self.network_stream_select_button.clicked.connect(self._on_network_stream_select_button_triggered)
# 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.Video, UiStrings().Video)
self.background_combo_box.setItemText(BackgroundType.Transparent,
translate('OpenLP.ThemeWizard', 'Transparent'))
self.background_combo_box.setItemText(BackgroundType.Stream,
translate('OpenLP.ThemeWizard', 'Live stream'))
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.stream_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
self.stream_label.setText('{text}:'.format(text=UiStrings().LiveStream))
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,
self.stream_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()
def _on_device_stream_select_button_triggered(self):
"""
Open the Stream selection form.
"""
if get_vlc():
stream_selector_form = StreamSelectorForm(self, self.set_stream, True)
# prefill in the form any device stream already defined
if self.stream_lineedit.text() and self.stream_lineedit.text().startswith("devicestream"):
stream_selector_form.set_mrl(self.stream_lineedit.text())
stream_selector_form.exec()
del stream_selector_form
else:
critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC is not available'),
translate('MediaPlugin.MediaItem', 'Device streaming support requires VLC.'))
def _on_network_stream_select_button_triggered(self):
"""
Open the Stream selection form.
"""
if get_vlc():
stream_selector_form = NetworkStreamSelectorForm(self, self.set_stream, True)
# prefill in the form any network stream already defined
if self.stream_lineedit.text() and self.stream_lineedit.text().startswith("networkstream"):
stream_selector_form.set_mrl(self.stream_lineedit.text())
stream_selector_form.exec()
del stream_selector_form
else:
critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC is not available'),
translate('MediaPlugin.MediaItem', 'Network streaming support requires VLC.'))
def set_stream(self, stream_str):
"""
callback method used to get the stream mrl and options
"""
self.stream_lineedit.setText(stream_str)
@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
@property
def stream_color(self):
return self.stream_color_button.color
@stream_color.setter
def stream_color(self, value):
self.stream_color_button.color = value
@property
def stream_mrl(self):
return self.stream_lineedit.text()
@stream_mrl.setter
def stream_mrl(self, value):
self.stream_lineedit.setText(value)