Add some small items from wish lists

Various cleanups.

--------------------------------------------------------------------------------
lp:~trb143/openlp/cleanups02182 (revision 2835)
https://ci.openlp.io/job/Branch-01-Pull/2480/                          [SUCCESS]
https://ci.openlp.io/job/Branch-02a-Linux-Tests/2381/                  [SUCCESS]
https://ci.openlp.io/job/Branch-02b-macOS-Tests/168/                   [FAILURE]
https://ci.openlp.io/job/Branch-03a-Build-Source/90/                 ...

bzr-revno: 2814
This commit is contained in:
Tim Bentley 2018-03-18 14:02:04 +00:00
commit 5b5dd16e13
18 changed files with 161 additions and 60 deletions

View File

@ -91,6 +91,7 @@ def controller_text(request):
item['text'] = str(frame['title'])
item['html'] = str(frame['title'])
item['selected'] = (live_controller.selected_row == index)
item['title'] = current_item.title
data.append(item)
json_data = {'results': {'slides': data}}
if current_item:
@ -117,12 +118,11 @@ def controller_set(request):
return {'results': {'success': True}}
@controller_endpoint.route('{action:next|previous}')
@controller_endpoint.route('{controller}/{action:next|previous}')
@requires_auth
def controller_direction(request, controller, action):
"""
Handles requests for setting service items in the slide controller
11
:param request: The http request object.
:param controller: the controller slides forward or backward.
:param action: the controller slides forward or backward.
@ -137,7 +137,7 @@ def controller_direction(request, controller, action):
def controller_direction_api(request, controller, action):
"""
Handles requests for setting service items in the slide controller
11
:param request: The http request object.
:param controller: the controller slides forward or backward.
:param action: the controller slides forward or backward.

View File

@ -62,7 +62,7 @@ def get_local_ip4():
"""
# Get the local IPv4 active address(es) that are NOT localhost (lo or '127.0.0.1')
log.debug('Getting local IPv4 interface(es) information')
MY_IP4 = {}
my_ip4 = {}
for iface in QNetworkInterface.allInterfaces():
if not iface.isValid() or not (iface.flags() & (QNetworkInterface.IsUp | QNetworkInterface.IsRunning)):
continue
@ -70,25 +70,25 @@ def get_local_ip4():
ip = address.ip()
# NOTE: Next line will skip if interface is localhost - keep for now until we decide about it later
# if (ip.protocol() == QAbstractSocket.IPv4Protocol) and (ip != QHostAddress.LocalHost):
if (ip.protocol() == QAbstractSocket.IPv4Protocol):
MY_IP4[iface.name()] = {'ip': ip.toString(),
if ip.protocol() == QAbstractSocket.IPv4Protocol:
my_ip4[iface.name()] = {'ip': ip.toString(),
'broadcast': address.broadcast().toString(),
'netmask': address.netmask().toString(),
'prefix': address.prefixLength(),
'localnet': QHostAddress(address.netmask().toIPv4Address() &
ip.toIPv4Address()).toString()
ip.toIPv4Address()).toString()
}
log.debug('Adding {iface} to active list'.format(iface=iface.name()))
if len(MY_IP4) == 1:
if 'lo' in MY_IP4:
if len(my_ip4) == 1:
if 'lo' in my_ip4:
# No active interfaces - so leave localhost in there
log.warning('No active IPv4 interfaces found except localhost')
else:
# Since we have a valid IP4 interface, remove localhost
log.debug('Found at least one IPv4 interface, removing localhost')
MY_IP4.pop('lo')
my_ip4.pop('lo')
return MY_IP4
return my_ip4
def trace_error_handler(logger):

View File

@ -121,6 +121,9 @@ class ItemCapabilities(object):
``HasThumbnails``
The item has related thumbnails available
``HasMetaData``
The item has Meta Data about item
"""
CanPreview = 1
CanEdit = 2
@ -143,6 +146,7 @@ class ItemCapabilities(object):
HasDisplayTitle = 19
HasNotes = 20
HasThumbnails = 21
HasMetaData = 22
class ServiceItem(RegistryProperties):
@ -200,6 +204,7 @@ class ServiceItem(RegistryProperties):
self.will_auto_start = False
self.has_original_files = True
self._new_item()
self.metadata = []
def _new_item(self):
"""
@ -375,7 +380,8 @@ class ServiceItem(RegistryProperties):
'background_audio': self.background_audio,
'theme_overwritten': self.theme_overwritten,
'will_auto_start': self.will_auto_start,
'processor': self.processor
'processor': self.processor,
'metadata': self.metadata
}
service_data = []
if self.service_item_type == ServiceItemType.Text:
@ -426,6 +432,7 @@ class ServiceItem(RegistryProperties):
self.will_auto_start = header.get('will_auto_start', False)
self.processor = header.get('processor', None)
self.has_original_files = True
self.metadata = header.get('item_meta_data', [])
if 'background_audio' in header:
self.background_audio = []
for file_path in header['background_audio']:

View File

@ -127,9 +127,6 @@ class UiFirstTimeWizard(object):
self.media_check_box.setChecked(True)
self.media_check_box.setObjectName('media_check_box')
self.plugin_layout.addWidget(self.media_check_box)
self.remote_check_box = QtWidgets.QCheckBox(self.plugin_page)
self.remote_check_box.setObjectName('remote_check_box')
self.plugin_layout.addWidget(self.remote_check_box)
self.song_usage_check_box = QtWidgets.QCheckBox(self.plugin_page)
self.song_usage_check_box.setChecked(True)
self.song_usage_check_box.setObjectName('song_usage_check_box')
@ -138,13 +135,6 @@ class UiFirstTimeWizard(object):
self.alert_check_box.setChecked(True)
self.alert_check_box.setObjectName('alert_check_box')
self.plugin_layout.addWidget(self.alert_check_box)
self.projectors_check_box = QtWidgets.QCheckBox(self.plugin_page)
# If visibility setting for projector panel is True, check the box.
if Settings().value('projector/show after wizard'):
self.projectors_check_box.setChecked(True)
self.projectors_check_box.setObjectName('projectors_check_box')
self.projectors_check_box.clicked.connect(self.on_projectors_check_box_clicked)
self.plugin_layout.addWidget(self.projectors_check_box)
first_time_wizard.setPage(FirstTimePage.Plugins, self.plugin_page)
# The song samples page
self.songs_page = QtWidgets.QWizardPage()
@ -256,13 +246,9 @@ class UiFirstTimeWizard(object):
self.presentation_check_box.setText(translate('OpenLP.FirstTimeWizard',
'Presentations Show .ppt, .odp and .pdf files'))
self.media_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Media Playback of Audio and Video files'))
self.remote_check_box.setText(str(UiStrings().WebDownloadText))
self.song_usage_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Song Usage Monitor'))
self.alert_check_box.setText(translate('OpenLP.FirstTimeWizard',
'Alerts Display informative messages while showing other slides'))
self.projectors_check_box.setText(translate('OpenLP.FirstTimeWizard',
'Projector Controller Control PJLink compatible projects on your'
' network from OpenLP'))
self.no_internet_page.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection'))
self.no_internet_page.setSubTitle(
translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.'))

View File

@ -179,7 +179,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
"""
Check to see if we have any media Player's available.
"""
log.debug('_check_available_media_players')
controller_dir = os.path.join('core', 'ui', 'media')
# Find all files that do not begin with '.' (lp:#1738047) and end with player.py
glob_pattern = os.path.join(controller_dir, '[!.]*player.py')

View File

@ -751,7 +751,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def context_menu(self, point):
"""
The Right click context menu from the Serviceitem list
The Right click context menu from the Service item list
:param point: The location of the cursor.
"""
@ -1136,7 +1136,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def on_delete_from_service(self):
"""
Remove the current ServiceItem from the list.
:param field:
"""
item = self.find_service_item()[0]
if item != -1:
@ -1205,6 +1204,9 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
tips.append('<strong>{text1}: </strong> {text2}'.format(text1=text1, text2=text2))
if item['service_item'].is_capable(ItemCapabilities.HasVariableStartTime):
tips.append(item['service_item'].get_media_time())
if item['service_item'].is_capable(ItemCapabilities.HasMetaData):
for meta in item['service_item'].metadata:
tips.append(meta)
tree_widget_item.setToolTip(0, '<br>'.join(tips))
tree_widget_item.setData(0, QtCore.Qt.UserRole, item['order'])
tree_widget_item.setSelected(item['selected'])
@ -1362,7 +1364,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def make_preview(self):
"""
Send the current item to the Preview slide controller
:param field:
"""
self.application.set_busy_cursor()
item, child = self.find_service_item()
@ -1387,7 +1388,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def on_double_click_live(self):
"""
Send the current item to the Live slide controller but triggered by a tablewidget click event.
:param field:
"""
self.list_double_clicked = True
self.make_live()
@ -1396,7 +1396,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
"""
If single click previewing is enabled, and triggered by a tablewidget click event,
start a timeout to verify a double-click hasn't triggered.
:param field:
"""
if Settings().value('advanced/single click service preview'):
if not self.list_double_clicked:
@ -1407,7 +1406,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def on_single_click_preview_timeout(self):
"""
If a single click ok, but double click not triggered, send the current item to the Preview slide controller.
:param field:
"""
if self.list_double_clicked:
# If a double click has registered, clear it.
@ -1447,7 +1445,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def remote_edit(self):
"""
Triggers a remote edit to a plugin to allow item to be edited.
:param field:
"""
item = self.find_service_item()[0]
if self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanEdit):
@ -1459,8 +1456,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def on_service_item_rename(self):
"""
Opens a dialog to rename the service item.
:param field: Not used, but PyQt needs this.
"""
item = self.find_service_item()[0]
if not self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanEditTitle):
@ -1477,7 +1472,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def create_custom(self):
"""
Saves the current text item as a custom slide
:param field:
"""
item = self.find_service_item()[0]
Registry().execute('custom_create_from_service', self.service_items[item]['service_item'])
@ -1597,8 +1591,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
def on_theme_change_action(self):
"""
Handles theme change events
:param field:
"""
theme = self.sender().objectName()
# No object name means that the "Default" theme is supposed to be used.

View File

@ -318,6 +318,10 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
tooltip=translate('OpenLP.SlideController',
'Edit and reload song preview.'),
triggers=self.on_edit_song)
self.toolbar.add_toolbar_action('clear', icon=':/general/general_delete.png',
tooltip=translate('OpenLP.SlideController',
'Clear'),
triggers=self.on_clear)
self.controller_layout.addWidget(self.toolbar)
# Build the Media Toolbar
self.media_controller.register_controller(self)
@ -356,7 +360,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
self.audio_time_label.setObjectName('audio_time_label')
self.toolbar.add_toolbar_widget(self.audio_time_label)
self.toolbar.set_widget_visible(AUDIO_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
self.toolbar.set_widget_visible('song_menu', False)
# Screen preview area
self.preview_frame = QtWidgets.QFrame(self.splitter)
self.preview_frame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
@ -427,7 +431,8 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
self.__add_actions_to_widget(self.controller)
else:
self.preview_widget.doubleClicked.connect(self.on_preview_double_click)
self.toolbar.set_widget_visible(['editSong'], False)
self.toolbar.set_widget_visible('editSong', False)
self.toolbar.set_widget_visible('clear', False)
self.controller.addActions([self.next_item, self.previous_item])
Registry().register_function('slidecontroller_{text}_stop_loop'.format(text=self.type_prefix),
self.on_stop_loop)
@ -726,7 +731,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
self.mediabar.hide()
self.song_menu.hide()
self.toolbar.set_widget_visible(LOOP_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
self.toolbar.set_widget_visible('song_menu', False)
# Reset the button
self.play_slides_once.setChecked(False)
self.play_slides_once.setIcon(build_icon(':/media/media_time.png'))
@ -737,7 +742,7 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
if item.is_text():
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
not self.song_menu.menu().isEmpty()):
self.toolbar.set_widget_visible(['song_menu'], True)
self.toolbar.set_widget_visible('song_menu', True)
if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1:
self.toolbar.set_widget_visible(LOOP_LIST)
if item.is_media():
@ -762,9 +767,10 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
# See bug #791050
self.toolbar.hide()
self.mediabar.hide()
self.toolbar.set_widget_visible(['editSong'], False)
self.toolbar.set_widget_visible('editSong', False)
self.toolbar.set_widget_visible('clear', True)
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
self.toolbar.set_widget_visible(['editSong'])
self.toolbar.set_widget_visible('editSong')
elif item.is_media():
self.mediabar.show()
self.previous_item.setVisible(not item.is_media())
@ -1381,6 +1387,14 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
if new_item:
self.add_service_item(new_item)
def on_clear(self):
"""
Clear the preview bar.
"""
self.preview_widget.clear_list()
self.toolbar.set_widget_visible('editSong', False)
self.toolbar.set_widget_visible('clear', False)
def on_preview_add_to_service(self):
"""
From the preview display request the Item to be added to service

View File

@ -428,8 +428,8 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
self.log_exception('Export Theme Failed')
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
translate('OpenLP.ThemeManager',
'The theme_name export failed because this error occurred: {err}')
.format(err=ose.strerror))
'The {theme_name} export failed because this error occurred: {err}')
.format(theme_name=theme_name, err=ose.strerror))
if theme_path.exists():
theme_path.rmtree(ignore_errors=True)
return False

View File

@ -67,14 +67,20 @@ class OpenLPToolbar(QtWidgets.QToolBar):
"""
Set the visibility for a widget or a list of widgets.
:param widgets: A list of string with widget object names.
:param widgets: A list of strings or individual string with widget object names.
:param visible: The new state as bool.
"""
for handle in widgets:
if handle in self.actions:
self.actions[handle].setVisible(visible)
if isinstance(widgets, list):
for handle in widgets:
if handle in self.actions:
self.actions[handle].setVisible(visible)
else:
log.warning('No handle "%s" in actions list.', str(handle))
else:
if widgets in self.actions:
self.actions[widgets].setVisible(visible)
else:
log.warning('No handle "%s" in actions list.', str(handle))
log.warning('No handle "%s" in actions list.', str(widgets))
def set_widget_enabled(self, widgets, enabled=True):
"""

View File

@ -146,6 +146,14 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
self.screen_ratio = screen_ratio
self.__recalculate_layout()
def clear_list(self):
"""
Clear the preview list
:return:
"""
self.setRowCount(0)
self.clear()
def replace_service_item(self, service_item, width, slide_number):
"""
Replace the current preview items with the ones in service_item and display the given slide
@ -156,8 +164,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
"""
self.service_item = service_item
self.setRowCount(0)
self.clear()
self.setColumnWidth(0, width)
self.clear_list()
row = 0
text = []
for frame_number, frame in enumerate(self.service_item.get_frames()):

View File

@ -30,6 +30,7 @@ from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus, \
check_item_selected
from openlp.core.lib.ui import create_widget_action
from openlp.plugins.custom.forms.editcustomform import EditCustomForm
from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder
from openlp.plugins.custom.lib.db import CustomSlide
@ -84,6 +85,12 @@ class CustomMediaItem(MediaManagerItem):
Registry().register_function('custom_preview', self.on_preview_click)
Registry().register_function('custom_create_from_service', self.create_from_service_item)
def add_custom_context_actions(self):
create_widget_action(self.list_view, separator=True)
create_widget_action(
self.list_view, text=translate('OpenLP.MediaManagerItem', '&Clone'), icon=':/general/general_clone.png',
triggers=self.on_clone_click)
def config_update(self):
"""
Config has been updated so reload values
@ -243,6 +250,23 @@ class CustomMediaItem(MediaManagerItem):
service_item.raw_footer.append('')
return True
def on_clone_click(self):
"""
Clone the selected Custom item
"""
item = self.list_view.currentItem()
item_id = item.data(QtCore.Qt.UserRole)
old_custom_slide = self.plugin.db_manager.get_object(CustomSlide, item_id)
new_custom_slide = CustomSlide()
new_custom_slide.title = '{title} <{text}>'.format(title=old_custom_slide.title,
text=translate('CustomPlugin.MediaItem',
'copy', 'For item cloning'))
new_custom_slide.text = old_custom_slide.text
new_custom_slide.credits = old_custom_slide.credits
new_custom_slide.theme_name = old_custom_slide.theme_name
self.plugin.db_manager.save_object(new_custom_slide)
self.on_search_text_button_clicked()
def on_search_text_button_clicked(self):
"""
Search the plugin database

View File

@ -164,7 +164,7 @@ class Song(BaseModel):
"""
Add a Songbook Entry to the song if it not yet exists
:param songbook_name: Name of the Songbook.
:param songbook: Name of the Songbook.
:param entry: Entry in the Songbook (usually a number)
"""
for songbook_entry in self.songbook_entries:

View File

@ -572,10 +572,19 @@ class SongMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
service_item.add_capability(ItemCapabilities.AddIfNewItem)
service_item.add_capability(ItemCapabilities.CanSoftBreak)
service_item.add_capability(ItemCapabilities.HasMetaData)
song = self.plugin.manager.get_object(Song, item_id)
service_item.theme = song.theme_name
service_item.edit_id = item_id
verse_list = SongXML().get_verses(song.lyrics)
if Settings().value('songs/add songbook slide') and song.songbook_entries:
first_slide = '\n'
for songbook_entry in song.songbook_entries:
first_slide = first_slide + '{book}/{num}/{pub}\n\n'.format(book=songbook_entry.songbook.name,
num=songbook_entry.entry,
pub=songbook_entry.songbook.publisher)
service_item.add_from_text(first_slide, 'O1')
# no verse list or only 1 space (in error)
verse_tags_translated = False
if VerseType.from_translated_string(str(verse_list[0][0]['type'])) is not None:
@ -622,6 +631,9 @@ class SongMediaItem(MediaManagerItem):
if song.media_files:
service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
service_item.background_audio = [m.file_path for m in song.media_files]
item.metadata.append('<em>{label}:</em> {media}'.
format(label=translate('SongsPlugin.MediaItem', 'Media'),
media=service_item.background_audio))
return True
def generate_footer(self, item, song):
@ -685,6 +697,23 @@ class SongMediaItem(MediaManagerItem):
if Settings().value('core/ccli number'):
item.raw_footer.append(translate('SongsPlugin.MediaItem',
'CCLI License: ') + Settings().value('core/ccli number'))
item.metadata.append('<em>{label}:</em> {title}'.format(label=translate('SongsPlugin.MediaItem', 'Title'),
title=song.title))
if song.alternate_title:
item.metadata.append('<em>{label}:</em> {title}'.
format(label=translate('SongsPlugin.MediaItem', 'Alt Title'),
title=song.alternate_title))
if song.songbook_entries:
for songbook_entry in song.songbook_entries:
item.metadata.append('<em>{label}:</em> {book}/{num}/{pub}'.
format(label=translate('SongsPlugin.MediaItem', 'Songbook'),
book=songbook_entry.songbook.name,
num=songbook_entry.entry,
pub=songbook_entry.songbook.publisher))
if song.topics:
for topics in song.topics:
item.metadata.append('<em>{label}:</em> {topic}'.
format(label=translate('SongsPlugin.MediaItem', 'Topic'), topic=topics.name))
return authors_all
def service_load(self, item):

View File

@ -51,6 +51,9 @@ class SongsTab(SettingsTab):
self.add_from_service_check_box = QtWidgets.QCheckBox(self.mode_group_box)
self.add_from_service_check_box.setObjectName('add_from_service_check_box')
self.mode_layout.addWidget(self.add_from_service_check_box)
self.songbook_slide_check_box = QtWidgets.QCheckBox(self.mode_group_box)
self.songbook_slide_check_box.setObjectName('songbook_slide_check_box')
self.mode_layout.addWidget(self.songbook_slide_check_box)
self.display_songbook_check_box = QtWidgets.QCheckBox(self.mode_group_box)
self.display_songbook_check_box.setObjectName('songbook_check_box')
self.mode_layout.addWidget(self.display_songbook_check_box)
@ -95,6 +98,7 @@ class SongsTab(SettingsTab):
self.tool_bar_active_check_box.stateChanged.connect(self.on_tool_bar_active_check_box_changed)
self.update_on_edit_check_box.stateChanged.connect(self.on_update_on_edit_check_box_changed)
self.add_from_service_check_box.stateChanged.connect(self.on_add_from_service_check_box_changed)
self.songbook_slide_check_box.stateChanged.connect(self.on_songbook_slide_check_box_changed)
self.display_songbook_check_box.stateChanged.connect(self.on_songbook_check_box_changed)
self.display_written_by_check_box.stateChanged.connect(self.on_written_by_check_box_changed)
self.display_copyright_check_box.stateChanged.connect(self.on_copyright_check_box_changed)
@ -111,6 +115,8 @@ class SongsTab(SettingsTab):
self.update_on_edit_check_box.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
self.add_from_service_check_box.setText(translate('SongsPlugin.SongsTab',
'Import missing songs from Service files'))
self.songbook_slide_check_box.setText(translate('SongsPlugin.SongsTab',
'Add Songbooks as first side'))
self.display_songbook_check_box.setText(translate('SongsPlugin.SongsTab', 'Display songbook in footer'))
self.display_written_by_check_box.setText(translate(
'SongsPlugin.SongsTab', 'Show "Written by:" in footer for unspecified authors'))
@ -141,6 +147,9 @@ class SongsTab(SettingsTab):
def on_add_from_service_check_box_changed(self, check_state):
self.update_load = (check_state == QtCore.Qt.Checked)
def on_songbook_slide_check_box_changed(self, check_state):
self.songbook_slide = (check_state == QtCore.Qt.Checked)
def on_songbook_check_box_changed(self, check_state):
self.display_songbook = (check_state == QtCore.Qt.Checked)
@ -171,6 +180,7 @@ class SongsTab(SettingsTab):
self.tool_bar = settings.value('display songbar')
self.update_edit = settings.value('update service on edit')
self.update_load = settings.value('add song from service')
self.songbook_slide = settings.value('add songbook slide')
self.display_songbook = settings.value('display songbook')
self.display_written_by = settings.value('display written by')
self.display_copyright_symbol = settings.value('display copyright symbol')
@ -208,6 +218,7 @@ class SongsTab(SettingsTab):
settings.setValue('mainview chords', self.mainview_chords)
settings.setValue('disable chords import', self.disable_chords_import)
settings.setValue('chord notation', self.chord_notation)
settings.setValue('add songbook slide', self.songbook_slide)
settings.endGroup()
if self.tab_visited:
self.settings_form.register_post_process('songs_config_updated')

View File

@ -61,6 +61,7 @@ __default_settings__ = {
'songs/last import type': SongFormat.OpenLyrics,
'songs/update service on edit': False,
'songs/add song from service': True,
'songs/add songbook slide': False,
'songs/display songbar': True,
'songs/display songbook': False,
'songs/display written by': True,

View File

@ -25,6 +25,7 @@ import asyncio
import websockets
import random
async def tester():
async with websockets.connect('ws://localhost:4317/poll') as websocket:

View File

@ -20,10 +20,10 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from unittest import TestCase
from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock
from openlp.core.common.registry import Registry
from openlp.core.api.endpoint.controller import controller_text
from openlp.core.api.endpoint.controller import controller_text, controller_direction
class TestController(TestCase):
@ -42,7 +42,7 @@ class TestController(TestCase):
def test_controller_text(self):
"""
Remote Deploy tests - test the dummy zip file is processed correctly
Remote API Tests : test the controller text method can be called
"""
# GIVEN: A mocked service with a dummy service item
self.mocked_live_controller.service_item = MagicMock()
@ -52,3 +52,25 @@ class TestController(TestCase):
results = ret['results']
assert isinstance(results['item'], MagicMock)
assert len(results['slides']) == 0
def test_controller_direction_next(self):
"""
Text the live next method is triggered
"""
# GIVEN: A mocked service with a dummy service item
self.mocked_live_controller.service_item = MagicMock()
# WHEN: I trigger the method
controller_direction(None, 'live', 'next')
# THEN: The correct method is called
self.mocked_live_controller.slidecontroller_live_next.emit.assert_called_once_with()
def test_controller_direction_previous(self):
"""
Text the live next method is triggered
"""
# GIVEN: A mocked service with a dummy service item
self.mocked_live_controller.service_item = MagicMock()
# WHEN: I trigger the method
controller_direction(None, 'live', 'previous')
# THEN: The correct method is called
self.mocked_live_controller.slidecontroller_live_previous.emit.assert_called_once_with()

View File

@ -431,14 +431,16 @@ class TestMediaItem(TestCase, TestMixin):
# GIVEN: A Song and a Service Item
song = Song()
song.title = 'My Song'
song.alternate_title = ''
song.copyright = 'My copyright'
song.authors_songs = []
song.songbook_entries = []
song.ccli_number = ''
song.topics = None
book1 = MagicMock()
book1.name = "My songbook"
book1.name = 'My songbook'
book2 = MagicMock()
book2.name = "Thy songbook"
book2.name = 'Thy songbook'
song.songbookentries = []
song.add_songbook_entry(book1, '12')
song.add_songbook_entry(book2, '502A')