More stuff working! Now you can see the text items in the slide controller and you can change the current slide

This commit is contained in:
Raoul Snyman 2018-03-27 22:39:47 -07:00
parent 8b826f29c4
commit 1a744383e5
7 changed files with 198 additions and 165 deletions

View File

@ -226,15 +226,24 @@ AudioPlayer.prototype.play = function () {
console.warn("No track currently paused and no track specified, doing nothing."); console.warn("No track currently paused and no track specified, doing nothing.");
} }
}; };
/**
* Pause
*/
AudioPlayer.prototype.pause = function () { AudioPlayer.prototype.pause = function () {
this._audioElement.pause(); this._audioElement.pause();
this._state = AudioState.Paused; this._state = AudioState.Paused;
}; };
/**
* Stop playing
*/
AudioPlayer.prototype.stop = function () { AudioPlayer.prototype.stop = function () {
this._audioElement.pause(); this._audioElement.pause();
this._audioElement.src = ""; this._audioElement.src = "";
this._state = AudioState.Stopped; this._state = AudioState.Stopped;
}; };
/** /**
* The Display object is what we use from OpenLP * The Display object is what we use from OpenLP
*/ */
@ -250,8 +259,8 @@ var Display = {
overview: false, overview: false,
center: false, center: false,
help: false, help: false,
transition: "slide", transition: "none",
backgroundTransition: "fade", backgroundTransition: "none",
viewDistance: 9999, viewDistance: 9999,
width: "100%", width: "100%",
height: "100%" height: "100%"
@ -321,15 +330,15 @@ var Display = {
slides.forEach(function (slide) { slides.forEach(function (slide) {
Display.addTextSlide(slide.verse, slide.text, false); Display.addTextSlide(slide.verse, slide.text, false);
}); });
this.reinit(); Display.reinit();
Display.goToSlide(0);
}, },
/** /**
* Set image slides * Set image slides
* @param {Object[]} slides - A list of images to add as JS objects [{"file": "url/to/file"}] * @param {Object[]} slides - A list of images to add as JS objects [{"file": "url/to/file"}]
*/ */
setImageSlides: function (slides) { setImageSlides: function (slides) {
var $this = this; Display.clearSlides();
$this.clearSlides();
var slidesDiv = $(".slides")[0]; var slidesDiv = $(".slides")[0];
slides.forEach(function (slide, index) { slides.forEach(function (slide, index) {
var section = document.createElement("section"); var section = document.createElement("section");
@ -340,9 +349,9 @@ var Display = {
img.setAttribute("style", "height: 100%; width: 100%;"); img.setAttribute("style", "height: 100%; width: 100%;");
section.appendChild(img); section.appendChild(img);
slidesDiv.appendChild(section); slidesDiv.appendChild(section);
$this._slides[index.toString()] = index; Display._slides[index.toString()] = index;
}); });
this.reinit(); Display.reinit();
}, },
/** /**
* Set a video * Set a video
@ -461,7 +470,12 @@ var Display = {
* @param slide The slide number or name, e.g. "v1", 0 * @param slide The slide number or name, e.g. "v1", 0
*/ */
goToSlide: function (slide) { goToSlide: function (slide) {
Reveal.slide(this._slides[slide]); if (this._slides.hasOwnProperty(slide)) {
Reveal.slide(this._slides[slide]);
}
else {
Reveal.slide(slide);
}
}, },
/** /**
* Go to the next slide in the list * Go to the next slide in the list

View File

@ -337,10 +337,10 @@
/** /**
* Restarts up the presentation if the client is capable. * Restarts up the presentation if the client is capable.
*/ */
function reinitialize() { function reinitialize() {
initialized = false; initialized = false;
initialize(config); initialize(config);
} }
/** /**
* Inspect the client to see what it's capable of, this * Inspect the client to see what it's capable of, this

View File

@ -182,6 +182,14 @@ class DisplayWindow(QtWidgets.QWidget):
QtWidgets.QApplication.instance().processEvents() QtWidgets.QApplication.instance().processEvents()
return self.__script_result return self.__script_result
def go_to_slide(self, verse):
"""
Go to a particular slide.
:param str verse: The verse to go to, e.g. "V1" for songs, or just "0" for other types
"""
self.run_javascript('Display.goToSlide("{verse}");'.format(verse=verse))
def load_verses(self, verses): def load_verses(self, verses):
""" """
Set verses in the display Set verses in the display

View File

@ -24,7 +24,6 @@ The :mod:`serviceitem` provides the service item functionality including the
type and capability of an item. type and capability of an item.
""" """
import datetime import datetime
import html
import logging import logging
import ntpath import ntpath
import os import os
@ -36,9 +35,9 @@ from openlp.core.common import md5_hash
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
from openlp.core.common.mixins import RegistryProperties from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import Path from openlp.core.common.path import Path, path_to_str
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.display.render import remove_tags, render_tags, render_chords # from openlp.core.display.render import remove_tags, render_tags, render_chords
from openlp.core.lib import ImageSource, build_icon from openlp.core.lib import ImageSource, build_icon
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -163,6 +162,7 @@ class ServiceItem(RegistryProperties):
if plugin: if plugin:
self.name = plugin.name self.name = plugin.name
self.title = '' self.title = ''
self.slides = []
self.processor = None self.processor = None
self.audit = '' self.audit = ''
self.items = [] self.items = []
@ -171,8 +171,8 @@ class ServiceItem(RegistryProperties):
self.foot_text = '' self.foot_text = ''
self.theme = None self.theme = None
self.service_item_type = None self.service_item_type = None
self._raw_frames = [] # self._raw_frames = []
self._display_frames = [] # self._display_frames = []
self.unique_identifier = 0 self.unique_identifier = 0
self.notes = '' self.notes = ''
self.from_plugin = False self.from_plugin = False
@ -234,91 +234,91 @@ class ServiceItem(RegistryProperties):
self.icon = icon self.icon = icon
self.iconic_representation = build_icon(icon) self.iconic_representation = build_icon(icon)
def render(self, provides_own_theme_data=False): # def render(self, provides_own_theme_data=False):
""" # """
The render method is what generates the frames for the screen and obtains the display information from the # The render method is what generates the frames for the screen and obtains the display information from the
renderer. At this point all slides are built for the given display size. # renderer. At this point all slides are built for the given display size.
#
# :param provides_own_theme_data: This switch disables the usage of the item's theme. However, this is
# disabled by default. If this is used, it has to be taken care, that
# the renderer knows the correct theme data. However, this is needed
# for the theme manager.
# """
# log.debug('Render called')
# self._display_frames = []
# self.bg_image_bytes = None
# # if not provides_own_theme_data:
# # self.renderer.set_item_theme(self.theme)
# # self.theme_data, self.main, self.footer = self.renderer.pre_render()
# if self.service_item_type == ServiceItemType.Text:
# can_render_chords = hasattr(self, 'name') and self.name == 'songs' and Settings().value(
# 'songs/enable chords')
# log.debug('Formatting slides: {title}'.format(title=self.title))
# # Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
# # the dict instead of rendering them again.
# previous_pages = {}
# for slide in self._raw_frames:
# verse_tag = slide['verseTag']
# if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
# pages = previous_pages[verse_tag][1]
# else:
# # pages = self.renderer.format_slide(slide['raw_slide'], self)
# previous_pages[verse_tag] = (slide['raw_slide'], pages)
# for page in pages:
# page = page.replace('<br>', '{br}')
# html_data = render_tags(page.rstrip(), can_render_chords)
# new_frame = {
# 'title': remove_tags(page),
# 'text': remove_tags(page.rstrip(), can_render_chords),
# 'chords_text': render_chords(remove_tags(page.rstrip(), False)),
# 'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
# 'printing_html': render_tags(html.escape(page.rstrip()), can_render_chords, is_printing=True),
# 'verseTag': verse_tag,
# }
# self._display_frames.append(new_frame)
# elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
# pass
# else:
# log.error('Invalid value renderer: {item}'.format(item=self.service_item_type))
# self.title = remove_tags(self.title)
# # The footer should never be None, but to be compatible with a few
# # nightly builds between 1.9.4 and 1.9.5, we have to correct this to
# # avoid tracebacks.
# if self.raw_footer is None:
# self.raw_footer = []
# self.foot_text = '<br>'.join([_f for _f in self.raw_footer if _f])
:param provides_own_theme_data: This switch disables the usage of the item's theme. However, this is def add_from_image(self, filename, title, background=None, thumbnail=None):
disabled by default. If this is used, it has to be taken care, that
the renderer knows the correct theme data. However, this is needed
for the theme manager.
"""
log.debug('Render called')
self._display_frames = []
self.bg_image_bytes = None
# if not provides_own_theme_data:
# self.renderer.set_item_theme(self.theme)
# self.theme_data, self.main, self.footer = self.renderer.pre_render()
if self.service_item_type == ServiceItemType.Text:
can_render_chords = hasattr(self, 'name') and self.name == 'songs' and Settings().value(
'songs/enable chords')
log.debug('Formatting slides: {title}'.format(title=self.title))
# Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
# the dict instead of rendering them again.
previous_pages = {}
for slide in self._raw_frames:
verse_tag = slide['verseTag']
if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
pages = previous_pages[verse_tag][1]
else:
# pages = self.renderer.format_slide(slide['raw_slide'], self)
previous_pages[verse_tag] = (slide['raw_slide'], pages)
for page in pages:
page = page.replace('<br>', '{br}')
html_data = render_tags(page.rstrip(), can_render_chords)
new_frame = {
'title': remove_tags(page),
'text': remove_tags(page.rstrip(), can_render_chords),
'chords_text': render_chords(remove_tags(page.rstrip(), False)),
'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
'printing_html': render_tags(html.escape(page.rstrip()), can_render_chords, is_printing=True),
'verseTag': verse_tag,
}
self._display_frames.append(new_frame)
elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
pass
else:
log.error('Invalid value renderer: {item}'.format(item=self.service_item_type))
self.title = remove_tags(self.title)
# The footer should never be None, but to be compatible with a few
# nightly builds between 1.9.4 and 1.9.5, we have to correct this to
# avoid tracebacks.
if self.raw_footer is None:
self.raw_footer = []
self.foot_text = '<br>'.join([_f for _f in self.raw_footer if _f])
def add_from_image(self, path, title, background=None, thumbnail=None):
""" """
Add an image slide to the service item. Add an image slide to the service item.
:param path: The directory in which the image file is located. :param filename: The directory in which the image file is located.
:param title: A title for the slide in the service item. :param title: A title for the slide in the service item.
:param background: :param background: The background colour
:param thumbnail: Optional alternative thumbnail, used for remote thumbnails. :param thumbnail: Optional alternative thumbnail, used for remote thumbnails.
""" """
if background: if background:
self.image_border = background self.image_border = background
self.service_item_type = ServiceItemType.Image self.service_item_type = ServiceItemType.Image
if not thumbnail: slide = {'title': title, 'filename': filename}
self._raw_frames.append({'title': title, 'path': path}) if thumbnail:
else: slide['thumbnail'] = thumbnail
self._raw_frames.append({'title': title, 'path': path, 'image': thumbnail}) self.slides.append(slide)
self.image_manager.add_image(path, ImageSource.ImagePlugin, self.image_border) # self.image_manager.add_image(path, ImageSource.ImagePlugin, self.image_border)
self._new_item() self._new_item()
def add_from_text(self, raw_slide, verse_tag=None): def add_from_text(self, text, verse_tag=None):
""" """
Add a text slide to the service item. Add a text slide to the service item.
:param raw_slide: The raw text of the slide. :param text: The raw text of the slide.
:param verse_tag: :param verse_tag:
""" """
if verse_tag: if verse_tag:
verse_tag = verse_tag.upper() verse_tag = verse_tag.upper()
self.service_item_type = ServiceItemType.Text self.service_item_type = ServiceItemType.Text
title = raw_slide[:30].split('\n')[0] title = text[:30].split('\n')[0]
self._raw_frames.append({'title': title, 'raw_slide': raw_slide, 'verseTag': verse_tag}) self.slides.append({'title': title, 'text': text, 'verse': verse_tag})
self._new_item() self._new_item()
def add_from_command(self, path, file_name, image, display_title=None, notes=None): def add_from_command(self, path, file_name, image, display_title=None, notes=None):
@ -342,8 +342,8 @@ class ServiceItem(RegistryProperties):
file_location_hash = md5_hash(file_location.encode('utf-8')) file_location_hash = md5_hash(file_location.encode('utf-8'))
image = os.path.join(str(AppLocation.get_section_data_path(self.name)), 'thumbnails', image = os.path.join(str(AppLocation.get_section_data_path(self.name)), 'thumbnails',
file_location_hash, ntpath.basename(image)) file_location_hash, ntpath.basename(image))
self._raw_frames.append({'title': file_name, 'image': image, 'path': path, self.slides.append({'title': file_name, 'image': image, 'path': path,
'display_title': display_title, 'notes': notes}) 'display_title': display_title, 'notes': notes})
if self.is_capable(ItemCapabilities.HasThumbnails): if self.is_capable(ItemCapabilities.HasThumbnails):
self.image_manager.add_image(image, ImageSource.CommandPlugins, '#000000') self.image_manager.add_image(image, ImageSource.CommandPlugins, '#000000')
self._new_item() self._new_item()
@ -474,10 +474,10 @@ class ServiceItem(RegistryProperties):
or self.is_capable(ItemCapabilities.CanEditTitle): or self.is_capable(ItemCapabilities.CanEditTitle):
return self.title return self.title
else: else:
if len(self._raw_frames) > 1: if len(self.slides) > 1:
return self.title return self.title
else: else:
return self._raw_frames[0]['title'] return self.slides[0]['title']
def merge(self, other): def merge(self, other):
""" """
@ -665,22 +665,22 @@ class ServiceItem(RegistryProperties):
Validates a service item to make sure it is valid Validates a service item to make sure it is valid
""" """
self.is_valid = True self.is_valid = True
for frame in self._raw_frames: for slide in self.slides:
if self.is_image() and not os.path.exists(frame['path']): if self.is_image() and not os.path.exists(slide['filename']):
self.is_valid = False self.is_valid = False
break break
elif self.is_command(): elif self.is_command():
if self.is_capable(ItemCapabilities.IsOptical): if self.is_capable(ItemCapabilities.IsOptical):
if not os.path.exists(frame['title']): if not os.path.exists(slide['title']):
self.is_valid = False self.is_valid = False
break break
else: else:
file_name = os.path.join(frame['path'], frame['title']) file_name = os.path.join(slide['path'], slide['title'])
if not os.path.exists(file_name): if not os.path.exists(file_name):
self.is_valid = False self.is_valid = False
break break
if suffix_list and not self.is_text(): if suffix_list and not self.is_text():
file_suffix = frame['title'].split('.')[-1] file_suffix = slide['title'].split('.')[-1]
if file_suffix.lower() not in suffix_list: if file_suffix.lower() not in suffix_list:
self.is_valid = False self.is_valid = False
break break

View File

@ -1165,7 +1165,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
# Repaint the screen # Repaint the screen
self.service_manager_list.clear() self.service_manager_list.clear()
self.service_manager_list.clearSelection() self.service_manager_list.clearSelection()
for item_count, item in enumerate(self.service_items): for item_index, item in enumerate(self.service_items):
service_item_from_item = item['service_item'] service_item_from_item = item['service_item']
tree_widget_item = QtWidgets.QTreeWidgetItem(self.service_manager_list) tree_widget_item = QtWidgets.QTreeWidgetItem(self.service_manager_list)
if service_item_from_item.is_valid: if service_item_from_item.is_valid:
@ -1211,17 +1211,17 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
tree_widget_item.setData(0, QtCore.Qt.UserRole, item['order']) tree_widget_item.setData(0, QtCore.Qt.UserRole, item['order'])
tree_widget_item.setSelected(item['selected']) tree_widget_item.setSelected(item['selected'])
# Add the children to their parent tree_widget_item. # Add the children to their parent tree_widget_item.
for count, frame in enumerate(service_item_from_item.get_frames()): for slide_index, slide in enumerate(service_item_from_item.slides):
child = QtWidgets.QTreeWidgetItem(tree_widget_item) child = QtWidgets.QTreeWidgetItem(tree_widget_item)
# prefer to use a display_title # prefer to use a display_title
if service_item_from_item.is_capable(ItemCapabilities.HasDisplayTitle): if service_item_from_item.is_capable(ItemCapabilities.HasDisplayTitle):
text = frame['display_title'].replace('\n', ' ') text = slide['display_title'].replace('\n', ' ')
else: else:
text = frame['title'].replace('\n', ' ') text = slide['title'].replace('\n', ' ')
child.setText(0, text[:40]) child.setText(0, text[:40])
child.setData(0, QtCore.Qt.UserRole, count) child.setData(0, QtCore.Qt.UserRole, slide_index)
if service_item == item_count: if service_item == item_index:
if item['expanded'] and service_item_child == count: if item['expanded'] and service_item_child == slide_index:
self.service_manager_list.setCurrentItem(child) self.service_manager_list.setCurrentItem(child)
elif service_item_child == -1: elif service_item_child == -1:
self.service_manager_list.setCurrentItem(tree_widget_item) self.service_manager_list.setCurrentItem(tree_widget_item)
@ -1339,7 +1339,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.repaint_service_list(s_item, child) self.repaint_service_list(s_item, child)
self.live_controller.replace_service_manager_item(item) self.live_controller.replace_service_manager_item(item)
else: else:
item.render() # item.render()
# nothing selected for dnd # nothing selected for dnd
if self.drop_position == -1: if self.drop_position == -1:
if isinstance(item, list): if isinstance(item, list):

View File

@ -23,7 +23,6 @@
The :mod:`slidecontroller` module contains the most important part of OpenLP - the slide controller The :mod:`slidecontroller` module contains the most important part of OpenLP - the slide controller
""" """
import copy import copy
import os
from collections import deque from collections import deque
from threading import Lock from threading import Lock
@ -135,12 +134,15 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
""" """
Set up the display Set up the display
""" """
if not self.is_live:
return
if self.displays: if self.displays:
# Delete any existing displays # Delete any existing displays
del self.displays[:] del self.displays[:]
# for screen in self.screens: for screen in self.screens:
# display = DisplayWindow(self, self.screens.current) if screen.is_display:
# self.displays.append(display) display = DisplayWindow(self, screen)
self.displays.append(display)
# display.media_watcher.progress.connect(self.on_audio_time_remaining) # display.media_watcher.progress.connect(self.on_audio_time_remaining)
@property @property
@ -574,8 +576,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
""" """
Settings dialog has changed the screen size of adjust output and screen previews. Settings dialog has changed the screen size of adjust output and screen previews.
""" """
# rebuild display as screen size changed if self.is_live and self.displays:
if self.displays:
for display in self.displays: for display in self.displays:
display.resize(self.screens.current.display_geometry.size()) display.resize(self.screens.current.display_geometry.size())
# if self.is_live: # if self.is_live:
@ -683,7 +684,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
not self.song_menu.menu().isEmpty()): 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: if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1:
self.toolbar.set_widget_visible(LOOP_LIST) self.toolbar.set_widget_visible(LOOP_LIST)
if item.is_media(): if item.is_media():
self.mediabar.show() self.mediabar.show()
@ -737,14 +738,14 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
theme_name = item.theme if item.theme else Registry().get('theme_manager').global_theme theme_name = item.theme if item.theme else Registry().get('theme_manager').global_theme
self.preview_display.set_theme(Registry().get('theme_manager').get_theme_data(theme_name)) self.preview_display.set_theme(Registry().get('theme_manager').get_theme_data(theme_name))
if item.is_text(): if item.is_text():
self.preview_display.load_verses([{'verse': f['verseTag'], 'text': f['raw_slide']} self.preview_display.load_verses(item.slides)
for f in item._raw_frames]) elif item.is_image():
self.preview_display.show_display() self.preview_display.load_images(item.slides)
# slide_no = 0 slide_no = 0
# if self.song_edit: # if self.song_edit:
# slide_no = self.selected_row # slide_no = self.selected_row
# self.song_edit = False # self.song_edit = False
# self._process_item(item, slide_no) self._process_item(item, slide_no)
def replace_service_manager_item(self, item): def replace_service_manager_item(self, item):
""" """
@ -797,6 +798,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
old_item = self.service_item old_item = self.service_item
# rest to allow the remote pick up verse 1 if large imaged # rest to allow the remote pick up verse 1 if large imaged
self.selected_row = 0 self.selected_row = 0
self.preview_display.go_to_slide(0)
# take a copy not a link to the servicemanager copy. # take a copy not a link to the servicemanager copy.
self.service_item = copy.copy(service_item) self.service_item = copy.copy(service_item)
if self.service_item.is_command(): if self.service_item.is_command():
@ -811,40 +813,40 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.slide_list = {} self.slide_list = {}
if self.is_live: if self.is_live:
self.song_menu.menu().clear() self.song_menu.menu().clear()
if self.display.audio_player: # if self.display.audio_player:
self.display.audio_player.reset() # self.display.audio_player.reset()
self.set_audio_items_visibility(False) # self.set_audio_items_visibility(False)
self.audio_pause_item.setChecked(False) # self.audio_pause_item.setChecked(False)
# If the current item has background audio # # If the current item has background audio
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio): # if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
self.log_debug('Starting to play...') # self.log_debug('Starting to play...')
self.display.audio_player.add_to_playlist(self.service_item.background_audio) # self.display.audio_player.add_to_playlist(self.service_item.background_audio)
self.track_menu.clear() # self.track_menu.clear()
for counter in range(len(self.service_item.background_audio)): # for counter in range(len(self.service_item.background_audio)):
action = self.track_menu.addAction( # action = self.track_menu.addAction(
os.path.basename(str(self.service_item.background_audio[counter]))) # os.path.basename(str(self.service_item.background_audio[counter])))
action.setData(counter) # action.setData(counter)
action.triggered.connect(self.on_track_triggered) # action.triggered.connect(self.on_track_triggered)
self.display.audio_player.repeat = \ # self.display.audio_player.repeat = \
Settings().value(self.main_window.general_settings_section + '/audio repeat list') # Settings().value(self.main_window.general_settings_section + '/audio repeat list')
if Settings().value(self.main_window.general_settings_section + '/audio start paused'): # if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
self.audio_pause_item.setChecked(True) # self.audio_pause_item.setChecked(True)
self.display.audio_player.pause() # self.display.audio_player.pause()
else: # else:
self.display.audio_player.play() # self.display.audio_player.play()
self.set_audio_items_visibility(True) # self.set_audio_items_visibility(True)
row = 0 row = 0
width = self.main_window.control_splitter.sizes()[self.split] width = self.main_window.control_splitter.sizes()[self.split]
for frame_number, frame in enumerate(self.service_item.get_frames()): for slide_index, slide in enumerate(self.service_item.slides):
if self.service_item.is_text(): if self.service_item.is_text():
if frame['verseTag']: if slide['verse']:
# These tags are already translated. # These tags are already translated.
verse_def = frame['verseTag'] verse_def = slide['verse']
verse_def = '{def1}{def2}'.format(def1=verse_def[0], def2=verse_def[1:]) verse_def = '{def1}{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
two_line_def = '{def1}\n{def2}'.format(def1=verse_def[0], def2=verse_def[1:]) two_line_def = '{def1}\n{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
row = two_line_def row = two_line_def
if verse_def not in self.slide_list: if verse_def not in self.slide_list:
self.slide_list[verse_def] = frame_number self.slide_list[verse_def] = slide_index
if self.is_live: if self.is_live:
self.song_menu.menu().addAction(verse_def, self.on_song_bar_handler) self.song_menu.menu().addAction(verse_def, self.on_song_bar_handler)
else: else:
@ -854,16 +856,16 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
row += 1 row += 1
self.slide_list[str(row)] = row - 1 self.slide_list[str(row)] = row - 1
# If current slide set background to image # If current slide set background to image
if not self.service_item.is_command() and frame_number == slide_no: if not self.service_item.is_command() and slide_index == slide_no:
self.service_item.bg_image_bytes = \ self.service_item.bg_image_bytes = \
self.image_manager.get_image_bytes(frame['path'], ImageSource.ImagePlugin) self.image_manager.get_image_bytes(slide['filename'], ImageSource.ImagePlugin)
self.preview_widget.replace_service_item(self.service_item, width, slide_no) self.preview_widget.replace_service_item(self.service_item, width, slide_no)
self.enable_tool_bar(self.service_item) self.enable_tool_bar(self.service_item)
# Pass to display for viewing. # Pass to display for viewing.
# Postpone image build, we need to do this later to avoid the theme # Postpone image build, we need to do this later to avoid the theme
# flashing on the screen # flashing on the screen
if not self.service_item.is_image(): # if not self.service_item.is_image():
self.display.build_html(self.service_item) # self.display.build_html(self.service_item)
if self.service_item.is_media(): if self.service_item.is_media():
self.on_media_start(self.service_item) self.on_media_start(self.service_item)
self.slide_selected(True) self.slide_selected(True)
@ -1098,7 +1100,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
if not start: if not start:
Registry().execute('slidecontroller_live_unblank') Registry().execute('slidecontroller_live_unblank')
row = self.preview_widget.current_slide_number() row = self.preview_widget.current_slide_number()
old_selected_row = self.selected_row # old_selected_row = self.selected_row
self.selected_row = 0 self.selected_row = 0
if -1 < row < self.preview_widget.slide_count(): if -1 < row < self.preview_widget.slide_count():
if self.service_item.is_command(): if self.service_item.is_command():
@ -1106,20 +1108,26 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
Registry().execute('{text}_slide'.format(text=self.service_item.name.lower()), Registry().execute('{text}_slide'.format(text=self.service_item.name.lower()),
[self.service_item, self.is_live, row]) [self.service_item, self.is_live, row])
else: else:
to_display = self.service_item.get_rendered_frame(row) # to_display = self.service_item.get_rendered_frame(row)
if self.service_item.is_text(): if self.service_item.is_text():
self.display.text(to_display, row != old_selected_row) for display in self.displays:
display.go_to_slide(row)
# self.display.text(to_display, row != old_selected_row)
else: else:
if start: if start:
self.display.build_html(self.service_item, to_display) for display in self.displays:
display.load_images([])
# self.display.build_html(self.service_item, to_display)
else: else:
self.display.image(to_display) for display in self.displays:
display.go_to_slide(row)
# self.display.image(to_display)
# reset the store used to display first image # reset the store used to display first image
self.service_item.bg_image_bytes = None self.service_item.bg_image_bytes = None
self.selected_row = row self.selected_row = row
self.update_preview() self.update_preview()
self.preview_widget.change_slide(row) self.preview_widget.change_slide(row)
self.display.setFocus() # TODO: self.display.setFocus()
# Release lock # Release lock
self.slide_selected_lock.release() self.slide_selected_lock.release()
@ -1137,7 +1145,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
""" """
This updates the preview frame, for example after changing a slide or using *Blank to Theme*. This updates the preview frame, for example after changing a slide or using *Blank to Theme*.
""" """
self.log_debug('update_preview {text} '.format(text=self.screens.current['primary'])) self.log_debug('update_preview {text} '.format(text=self.screens.current))
if self.service_item and self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay): if self.service_item and self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
if self.is_live: if self.is_live:
# If live, grab screen-cap of main display now # If live, grab screen-cap of main display now
@ -1155,9 +1163,11 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio()) self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
self.slide_preview.setPixmap(self.slide_image) self.slide_preview.setPixmap(self.slide_image)
else: else:
self.slide_image = self.display.preview() print('Updating preview ... need to figure out what is supposed to happen here')
self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio()) self.preview_display.go_to_slide(self.selected_row)
self.slide_preview.setPixmap(self.slide_image) # self.slide_image = self.display.preview()
# self.slide_image.setDevicePixelRatio(self.main_window.devicePixelRatio())
# self.slide_preview.setPixmap(self.slide_image)
self.slide_count += 1 self.slide_count += 1
def grab_maindisplay(self): def grab_maindisplay(self):

View File

@ -120,8 +120,8 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
self.auto_row_height = max(self.viewport().height() / (-1 * max_img_row_height), 100) self.auto_row_height = max(self.viewport().height() / (-1 * max_img_row_height), 100)
height = min(height, self.auto_row_height) height = min(height, self.auto_row_height)
# Apply new height to slides # Apply new height to slides
for frame_number in range(len(self.service_item.get_frames())): for slide_index in range(len(self.service_item.slides)):
self.setRowHeight(frame_number, height) self.setRowHeight(slide_index, height)
def row_resized(self, row, old_height, new_height): def row_resized(self, row, old_height, new_height):
""" """
@ -134,7 +134,8 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
# Get and validate label widget containing slide & adjust max width # Get and validate label widget containing slide & adjust max width
try: try:
self.cellWidget(row, 0).children()[1].setMaximumWidth(new_height * self.screen_ratio) self.cellWidget(row, 0).children()[1].setMaximumWidth(new_height * self.screen_ratio)
except: except Exception:
# TODO: Figure out what sort of exceptions are thrown
return return
def screen_size_changed(self, screen_ratio): def screen_size_changed(self, screen_ratio):
@ -160,20 +161,20 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
self.setColumnWidth(0, width) self.setColumnWidth(0, width)
row = 0 row = 0
text = [] text = []
for frame_number, frame in enumerate(self.service_item.get_frames()): for slide_index, slide in enumerate(self.service_item.slides):
self.setRowCount(self.slide_count() + 1) self.setRowCount(self.slide_count() + 1)
item = QtWidgets.QTableWidgetItem() item = QtWidgets.QTableWidgetItem()
slide_height = 0 slide_height = 0
if self.service_item.is_text(): if self.service_item.is_text():
if frame['verseTag']: if slide['verse']:
# These tags are already translated. # These tags are already translated.
verse_def = frame['verseTag'] verse_def = slide['verse']
verse_def = '%s%s' % (verse_def[0], verse_def[1:]) verse_def = '%s%s' % (verse_def[0], verse_def[1:])
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:]) two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
row = two_line_def row = two_line_def
else: else:
row += 1 row += 1
item.setText(frame['text']) item.setText(slide['text'])
else: else:
label = QtWidgets.QLabel() label = QtWidgets.QLabel()
label.setContentsMargins(4, 4, 4, 4) label.setContentsMargins(4, 4, 4, 4)
@ -183,12 +184,12 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
label.setScaledContents(True) label.setScaledContents(True)
if self.service_item.is_command(): if self.service_item.is_command():
if self.service_item.is_capable(ItemCapabilities.HasThumbnails): if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
image = self.image_manager.get_image(frame['image'], ImageSource.CommandPlugins) image = self.image_manager.get_image(slide['image'], ImageSource.CommandPlugins)
pixmap = QtGui.QPixmap.fromImage(image) pixmap = QtGui.QPixmap.fromImage(image)
else: else:
pixmap = QtGui.QPixmap(frame['image']) pixmap = QtGui.QPixmap(slide['image'])
else: else:
image = self.image_manager.get_image(frame['path'], ImageSource.ImagePlugin) image = self.image_manager.get_image(slide['filename'], ImageSource.ImagePlugin)
pixmap = QtGui.QPixmap.fromImage(image) pixmap = QtGui.QPixmap.fromImage(image)
pixmap.setDevicePixelRatio(label.devicePixelRatio()) pixmap.setDevicePixelRatio(label.devicePixelRatio())
label.setPixmap(pixmap) label.setPixmap(pixmap)
@ -212,15 +213,15 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
hbox.addStretch(0) hbox.addStretch(0)
container.setLayout(hbox) container.setLayout(hbox)
# Add to table # Add to table
self.setCellWidget(frame_number, 0, container) self.setCellWidget(slide_index, 0, container)
else: else:
# Add to table # Add to table
self.setCellWidget(frame_number, 0, label) self.setCellWidget(slide_index, 0, label)
row += 1 row += 1
text.append(str(row)) text.append(str(row))
self.setItem(frame_number, 0, item) self.setItem(slide_index, 0, item)
if slide_height: if slide_height:
self.setRowHeight(frame_number, slide_height) self.setRowHeight(slide_index, slide_height)
self.setVerticalHeaderLabels(text) self.setVerticalHeaderLabels(text)
if self.service_item.is_text(): if self.service_item.is_text():
self.resizeRowsToContents() self.resizeRowsToContents()