forked from openlp/openlp
-- General code cleanup to better match the architecture
-- Added thumbnails to the remote display -- Modify the service list to use the displaytitle
This commit is contained in:
parent
3bbaff362d
commit
00fd7f01f7
@ -107,6 +107,16 @@ class ItemCapabilities(object):
|
|||||||
``CanAutoStartForLive``
|
``CanAutoStartForLive``
|
||||||
The capability to ignore the do not play if display blank flag.
|
The capability to ignore the do not play if display blank flag.
|
||||||
|
|
||||||
|
``HasDisplayTitle``
|
||||||
|
The item contains 'displaytitle' on every frame which should be
|
||||||
|
preferred over 'title' when displaying the item
|
||||||
|
|
||||||
|
``HasNotes``
|
||||||
|
The item contains 'notes'
|
||||||
|
|
||||||
|
``HasThumbnails``
|
||||||
|
The item has related thumbnails available
|
||||||
|
|
||||||
"""
|
"""
|
||||||
CanPreview = 1
|
CanPreview = 1
|
||||||
CanEdit = 2
|
CanEdit = 2
|
||||||
@ -124,6 +134,9 @@ class ItemCapabilities(object):
|
|||||||
CanWordSplit = 14
|
CanWordSplit = 14
|
||||||
HasBackgroundAudio = 15
|
HasBackgroundAudio = 15
|
||||||
CanAutoStartForLive = 16
|
CanAutoStartForLive = 16
|
||||||
|
HasDisplayTitle = 17
|
||||||
|
HasNotes = 18
|
||||||
|
HasThumbnails = 19
|
||||||
|
|
||||||
|
|
||||||
class ServiceItem(object):
|
class ServiceItem(object):
|
||||||
@ -303,7 +316,7 @@ class ServiceItem(object):
|
|||||||
self._raw_frames.append({'title': title, 'raw_slide': raw_slide, 'verseTag': verse_tag})
|
self._raw_frames.append({'title': title, 'raw_slide': raw_slide, 'verseTag': verse_tag})
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def add_from_command(self, path, file_name, image):
|
def add_from_command(self, path, file_name, image, displaytitle=None, notes=None):
|
||||||
"""
|
"""
|
||||||
Add a slide from a command.
|
Add a slide from a command.
|
||||||
|
|
||||||
@ -317,27 +330,8 @@ class ServiceItem(object):
|
|||||||
The command of/for the slide.
|
The command of/for the slide.
|
||||||
"""
|
"""
|
||||||
self.service_item_type = ServiceItemType.Command
|
self.service_item_type = ServiceItemType.Command
|
||||||
self._raw_frames.append({'title': file_name, 'image': image, 'path': path})
|
self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
|
||||||
self._new_item()
|
'displaytitle': displaytitle, 'notes': notes})
|
||||||
|
|
||||||
def add_from_presentation(self, path, file_name, image, displaytitle, notes):
|
|
||||||
"""
|
|
||||||
Add a slide from a presentation.
|
|
||||||
|
|
||||||
``path``
|
|
||||||
The path of the presentation
|
|
||||||
|
|
||||||
``file_name``
|
|
||||||
The filename of the presentation
|
|
||||||
|
|
||||||
``image``
|
|
||||||
Full path (including file name) to the thumbnail
|
|
||||||
|
|
||||||
``displaytitle``
|
|
||||||
The title to display on the list and remote
|
|
||||||
"""
|
|
||||||
self.service_item_type = ServiceItemType.Command
|
|
||||||
self._raw_frames.append({'title': file_name, 'image': image, 'path': path, 'displaytitle': displaytitle, 'notes': notes})
|
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def get_service_repr(self, lite_save):
|
def get_service_repr(self, lite_save):
|
||||||
@ -382,11 +376,8 @@ class ServiceItem(object):
|
|||||||
service_data = [slide['title'] for slide in self._raw_frames]
|
service_data = [slide['title'] for slide in self._raw_frames]
|
||||||
elif self.service_item_type == ServiceItemType.Command:
|
elif self.service_item_type == ServiceItemType.Command:
|
||||||
for slide in self._raw_frames:
|
for slide in self._raw_frames:
|
||||||
#if len(slide['displaytitle'])>0:
|
|
||||||
service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path'],
|
service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path'],
|
||||||
'displaytitle': slide['displaytitle'], 'notes': slide['notes']})
|
'displaytitle': slide['displaytitle'], 'notes': slide['notes']})
|
||||||
#else:
|
|
||||||
# service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path']})
|
|
||||||
return {'header': service_header, 'data': service_data}
|
return {'header': service_header, 'data': service_data}
|
||||||
|
|
||||||
def set_from_service(self, serviceitem, path=None):
|
def set_from_service(self, serviceitem, path=None):
|
||||||
@ -458,10 +449,8 @@ class ServiceItem(object):
|
|||||||
self.title = text_image['title']
|
self.title = text_image['title']
|
||||||
if path:
|
if path:
|
||||||
self.has_original_files = False
|
self.has_original_files = False
|
||||||
if serviceitem['serviceitem']['header']['plugin']=='presentations':
|
self.add_from_command(path, text_image['title'], text_image['image'],
|
||||||
self.add_from_presentation(path, text_image['title'], text_image['image'], text_image['displaytitle'], text_image['notes'])
|
text_image['displaytitle'], text_image['notes'])
|
||||||
else:
|
|
||||||
self.add_from_command(path, text_image['title'], text_image['image'])
|
|
||||||
else:
|
else:
|
||||||
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
|
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
@ -1185,7 +1185,14 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
|
|||||||
# Add the children to their parent treewidgetitem.
|
# Add the children to their parent treewidgetitem.
|
||||||
for count, frame in enumerate(serviceitem.get_frames()):
|
for count, frame in enumerate(serviceitem.get_frames()):
|
||||||
child = QtGui.QTreeWidgetItem(treewidgetitem)
|
child = QtGui.QTreeWidgetItem(treewidgetitem)
|
||||||
text = frame['title'].replace('\n', ' ')
|
# prefer to use a displaytitle
|
||||||
|
if serviceitem.is_capable(ItemCapabilities.HasDisplayTitle):
|
||||||
|
text = frame['displaytitle'].replace('\n',' ')
|
||||||
|
# oops, it is missing, let's make one up
|
||||||
|
if len(text.strip()) == 0:
|
||||||
|
text = '[slide ' + str(count+1) + ']'
|
||||||
|
else:
|
||||||
|
text = frame['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, count)
|
||||||
if service_item == item_count:
|
if service_item == item_count:
|
||||||
|
@ -466,6 +466,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
shape = page.getByIndex(index)
|
shape = page.getByIndex(index)
|
||||||
shapeType = shape.getShapetype()
|
shapeType = shape.getShapetype()
|
||||||
if shape.supportsService("com.sun.star.drawing.Text"):
|
if shape.supportsService("com.sun.star.drawing.Text"):
|
||||||
|
# if they requested title, make sure it is the title
|
||||||
if text_type!=TextType.Title or shapeType == "com.sun.star.presentation.TitleTextShape":
|
if text_type!=TextType.Title or shapeType == "com.sun.star.presentation.TitleTextShape":
|
||||||
text += shape.getString() + '\n'
|
text += shape.getString() + '\n'
|
||||||
return text
|
return text
|
||||||
@ -492,8 +493,3 @@ class ImpressDocument(PresentationDocument):
|
|||||||
fo.writelines(titles)
|
fo.writelines(titles)
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_titles_and_notes(self):
|
|
||||||
"""
|
|
||||||
let the super class handle it
|
|
||||||
"""
|
|
||||||
return super().get_titles_and_notes()
|
|
||||||
|
@ -250,6 +250,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
return False
|
return False
|
||||||
service_item.processor = self.display_type_combo_box.currentText()
|
service_item.processor = self.display_type_combo_box.currentText()
|
||||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||||
|
service_item.add_capability(ItemCapabilities.HasThumbnails)
|
||||||
if not self.display_type_combo_box.currentText():
|
if not self.display_type_combo_box.currentText():
|
||||||
return False
|
return False
|
||||||
for bitem in items:
|
for bitem in items:
|
||||||
@ -264,6 +265,10 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
controller = self.controllers[service_item.processor]
|
controller = self.controllers[service_item.processor]
|
||||||
doc = controller.add_document(filename)
|
doc = controller.add_document(filename)
|
||||||
titles, notes = doc.get_titles_and_notes()
|
titles, notes = doc.get_titles_and_notes()
|
||||||
|
if len(titles) > 0:
|
||||||
|
service_item.add_capability(ItemCapabilities.HasDisplayTitle)
|
||||||
|
if len(notes) > 0:
|
||||||
|
service_item.add_capability(ItemCapabilities.HasNotes)
|
||||||
if doc.get_thumbnail_path(1, True) is None:
|
if doc.get_thumbnail_path(1, True) is None:
|
||||||
doc.load_presentation()
|
doc.load_presentation()
|
||||||
i = 1
|
i = 1
|
||||||
@ -276,7 +281,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
note = ''
|
note = ''
|
||||||
if i <= len(notes):
|
if i <= len(notes):
|
||||||
note = notes[i-1]
|
note = notes[i-1]
|
||||||
service_item.add_from_presentation(path, name, img, title, note)
|
service_item.add_from_command(path, name, img, title, note)
|
||||||
i += 1
|
i += 1
|
||||||
img = doc.get_thumbnail_path(i, True)
|
img = doc.get_thumbnail_path(i, True)
|
||||||
doc.close_presentation()
|
doc.close_presentation()
|
||||||
|
@ -344,12 +344,6 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
fo.writelines(titles)
|
fo.writelines(titles)
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_titles_and_notes(self):
|
|
||||||
"""
|
|
||||||
let the super class handle it
|
|
||||||
"""
|
|
||||||
return super().get_titles_and_notes()
|
|
||||||
|
|
||||||
def _get_text_from_shapes(shapes):
|
def _get_text_from_shapes(shapes):
|
||||||
"""
|
"""
|
||||||
Returns any text extracted from the shapes on a presentation slide.
|
Returns any text extracted from the shapes on a presentation slide.
|
||||||
|
@ -179,12 +179,14 @@ class PptviewDocument(PresentationDocument):
|
|||||||
index = -1
|
index = -1
|
||||||
listToAdd = None
|
listToAdd = None
|
||||||
|
|
||||||
|
# check if it is a slide
|
||||||
match = re.search("slides/slide(.+)\.xml", zip_info.filename)
|
match = re.search("slides/slide(.+)\.xml", zip_info.filename)
|
||||||
if match:
|
if match:
|
||||||
index = int(match.group(1))-1
|
index = int(match.group(1))-1
|
||||||
nodeType = 'ctrTitle'
|
nodeType = 'ctrTitle'
|
||||||
listToAdd = titles
|
listToAdd = titles
|
||||||
|
|
||||||
|
# or a note
|
||||||
match = re.search("notesSlides/notesSlide(.+)\.xml", zip_info.filename)
|
match = re.search("notesSlides/notesSlide(.+)\.xml", zip_info.filename)
|
||||||
if match:
|
if match:
|
||||||
index = int(match.group(1))-1
|
index = int(match.group(1))-1
|
||||||
@ -197,7 +199,9 @@ class PptviewDocument(PresentationDocument):
|
|||||||
tree = ElementTree.parse(zipped_file)
|
tree = ElementTree.parse(zipped_file)
|
||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
nodes = tree.getroot().findall(".//p:ph[@type='" + nodeType + "']../../..//p:txBody//a:t", namespaces=namespaces)
|
nodes = tree.getroot().findall(".//p:ph[@type='" + nodeType + "']../../..//p:txBody//a:t",
|
||||||
|
namespaces=namespaces)
|
||||||
|
# if we found any content
|
||||||
if nodes and len(nodes)>0:
|
if nodes and len(nodes)>0:
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
if len(text) > 0:
|
if len(text) > 0:
|
||||||
@ -205,7 +209,7 @@ class PptviewDocument(PresentationDocument):
|
|||||||
text += node.text
|
text += node.text
|
||||||
print( 'slide file: ' + zip_info.filename + ' ' + text )
|
print( 'slide file: ' + zip_info.filename + ' ' + text )
|
||||||
|
|
||||||
# let's remove the nl from the titles and just add one at the end
|
# let's remove the \n from the titles and just add one at the end
|
||||||
if nodeType == 'ctrTitle':
|
if nodeType == 'ctrTitle':
|
||||||
text = text.replace('\n',' ').replace('\x0b', ' ') + '\n'
|
text = text.replace('\n',' ').replace('\x0b', ' ') + '\n'
|
||||||
listToAdd[index] = text
|
listToAdd[index] = text
|
||||||
@ -319,9 +323,3 @@ class PptviewDocument(PresentationDocument):
|
|||||||
Triggers the previous slide on the running presentation.
|
Triggers the previous slide on the running presentation.
|
||||||
"""
|
"""
|
||||||
self.controller.process.PrevStep(self.ppt_id)
|
self.controller.process.PrevStep(self.ppt_id)
|
||||||
|
|
||||||
def get_titles_and_notes(self):
|
|
||||||
"""
|
|
||||||
let the super class handle it
|
|
||||||
"""
|
|
||||||
return super().get_titles_and_notes()
|
|
||||||
|
@ -209,7 +209,8 @@ class PPTViewer(QtGui.QWidget):
|
|||||||
tree = ElementTree.parse(zipped_file)
|
tree = ElementTree.parse(zipped_file)
|
||||||
text = ''
|
text = ''
|
||||||
|
|
||||||
nodes = tree.getroot().findall(".//p:ph[@type='" + nodeType + "']../../..//p:txBody//a:t", namespaces=namespaces)
|
nodes = tree.getroot().findall(".//p:ph[@type='" + nodeType + "']../../..//p:txBody//a:t",
|
||||||
|
namespaces=namespaces)
|
||||||
if nodes and len(nodes)>0:
|
if nodes and len(nodes)>0:
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
if len(text) > 0:
|
if len(text) > 0:
|
||||||
|
@ -87,13 +87,21 @@ window.OpenLP = {
|
|||||||
var ul = $("#slide-controller > div[data-role=content] > ul[data-role=listview]");
|
var ul = $("#slide-controller > div[data-role=content] > ul[data-role=listview]");
|
||||||
ul.html("");
|
ul.html("");
|
||||||
for (idx in data.results.slides) {
|
for (idx in data.results.slides) {
|
||||||
var text = data.results.slides[idx]["tag"];
|
var slide = data.results.slides[idx];
|
||||||
|
var text = slide["tag"];
|
||||||
if (text != "") text = text + ": ";
|
if (text != "") text = text + ": ";
|
||||||
text = text + data.results.slides[idx]["text"];
|
if (slide["title"])
|
||||||
|
text += slide["title"]
|
||||||
|
else
|
||||||
|
text += slide["text"];
|
||||||
|
if (slide["notes"])
|
||||||
|
text += ("<div style='font-size:smaller;font-weight:normal'>" + slide["notes"] + "</div>");
|
||||||
text = text.replace(/\n/g, '<br />');
|
text = text.replace(/\n/g, '<br />');
|
||||||
|
if (slide["img"])
|
||||||
|
text += "<img src='" + slide["img"] + "'>";
|
||||||
var li = $("<li data-icon=\"false\">").append(
|
var li = $("<li data-icon=\"false\">").append(
|
||||||
$("<a href=\"#\">").attr("value", parseInt(idx, 10)).html(text));
|
$("<a href=\"#\">").attr("value", parseInt(idx, 10)).html(text));
|
||||||
if (data.results.slides[idx]["selected"]) {
|
if (slide["selected"]) {
|
||||||
li.attr("data-theme", "e");
|
li.attr("data-theme", "e");
|
||||||
}
|
}
|
||||||
li.children("a").click(OpenLP.setSlide);
|
li.children("a").click(OpenLP.setSlide);
|
||||||
|
@ -125,7 +125,7 @@ from urllib.parse import urlparse, parse_qs
|
|||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Registry, Settings, PluginStatus, StringContent, image_to_byte
|
from openlp.core.lib import Registry, Settings, PluginStatus, StringContent, image_to_byte, resize_image, ItemCapabilities
|
||||||
from openlp.core.utils import AppLocation, translate
|
from openlp.core.utils import AppLocation, translate
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -151,6 +151,7 @@ class HttpRouter(object):
|
|||||||
('^/(stage)$', {'function': self.serve_file, 'secure': False}),
|
('^/(stage)$', {'function': self.serve_file, 'secure': False}),
|
||||||
('^/(main)$', {'function': self.serve_file, 'secure': False}),
|
('^/(main)$', {'function': self.serve_file, 'secure': False}),
|
||||||
(r'^/files/(.*)$', {'function': self.serve_file, 'secure': False}),
|
(r'^/files/(.*)$', {'function': self.serve_file, 'secure': False}),
|
||||||
|
(r'^/(.*)/thumbnails/(.*)$', {'function': self.serve_thumbnail, 'secure': False}),
|
||||||
(r'^/api/poll$', {'function': self.poll, 'secure': False}),
|
(r'^/api/poll$', {'function': self.poll, 'secure': False}),
|
||||||
(r'^/main/poll$', {'function': self.main_poll, 'secure': False}),
|
(r'^/main/poll$', {'function': self.main_poll, 'secure': False}),
|
||||||
(r'^/main/image$', {'function': self.main_image, 'secure': False}),
|
(r'^/main/image$', {'function': self.main_image, 'secure': False}),
|
||||||
@ -347,26 +348,10 @@ class HttpRouter(object):
|
|||||||
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
||||||
if not path.startswith(self.html_dir):
|
if not path.startswith(self.html_dir):
|
||||||
return self.do_not_found()
|
return self.do_not_found()
|
||||||
ext = os.path.splitext(file_name)[1]
|
|
||||||
html = None
|
html = None
|
||||||
if ext == '.html':
|
if self.send_appropriate_header(file_name) == '.html':
|
||||||
self.send_header('Content-type', 'text/html')
|
|
||||||
variables = self.template_vars
|
variables = self.template_vars
|
||||||
html = Template(filename=path, input_encoding='utf-8', output_encoding='utf-8').render(**variables)
|
html = Template(filename=path, input_encoding='utf-8', output_encoding='utf-8').render(**variables)
|
||||||
elif ext == '.css':
|
|
||||||
self.send_header('Content-type', 'text/css')
|
|
||||||
elif ext == '.js':
|
|
||||||
self.send_header('Content-type', 'application/javascript')
|
|
||||||
elif ext == '.jpg':
|
|
||||||
self.send_header('Content-type', 'image/jpeg')
|
|
||||||
elif ext == '.gif':
|
|
||||||
self.send_header('Content-type', 'image/gif')
|
|
||||||
elif ext == '.ico':
|
|
||||||
self.send_header('Content-type', 'image/x-icon')
|
|
||||||
elif ext == '.png':
|
|
||||||
self.send_header('Content-type', 'image/png')
|
|
||||||
else:
|
|
||||||
self.send_header('Content-type', 'text/plain')
|
|
||||||
file_handle = None
|
file_handle = None
|
||||||
try:
|
try:
|
||||||
if html:
|
if html:
|
||||||
@ -383,6 +368,44 @@ class HttpRouter(object):
|
|||||||
file_handle.close()
|
file_handle.close()
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
def send_appropriate_header(self, file_name):
|
||||||
|
ext = os.path.splitext(file_name)[1]
|
||||||
|
if ext == '.html':
|
||||||
|
self.send_header('Content-type', 'text/html')
|
||||||
|
elif ext == '.css':
|
||||||
|
self.send_header('Content-type', 'text/css')
|
||||||
|
elif ext == '.js':
|
||||||
|
self.send_header('Content-type', 'application/javascript')
|
||||||
|
elif ext == '.jpg':
|
||||||
|
self.send_header('Content-type', 'image/jpeg')
|
||||||
|
elif ext == '.gif':
|
||||||
|
self.send_header('Content-type', 'image/gif')
|
||||||
|
elif ext == '.ico':
|
||||||
|
self.send_header('Content-type', 'image/x-icon')
|
||||||
|
elif ext == '.png':
|
||||||
|
self.send_header('Content-type', 'image/png')
|
||||||
|
else:
|
||||||
|
self.send_header('Content-type', 'text/plain')
|
||||||
|
return ext
|
||||||
|
|
||||||
|
def serve_thumbnail(self, controller_name=None, file_name=None):
|
||||||
|
"""
|
||||||
|
Serve an image file. If not found return 404.
|
||||||
|
"""
|
||||||
|
log.debug('serve thumbnail %s/thumbnails/%s' % (controller_name, file_name))
|
||||||
|
content = ''
|
||||||
|
full_path = os.path.join(AppLocation.get_section_data_path(controller_name),
|
||||||
|
'thumbnails/' + file_name.replace('/','\\') )
|
||||||
|
full_path = urllib.parse.unquote(full_path)
|
||||||
|
|
||||||
|
if os.path.exists(full_path):
|
||||||
|
self.send_appropriate_header(full_path)
|
||||||
|
file_handle = open(full_path, 'rb')
|
||||||
|
content = file_handle.read()
|
||||||
|
else:
|
||||||
|
content = self.do_not_found()
|
||||||
|
return content
|
||||||
|
|
||||||
def poll(self):
|
def poll(self):
|
||||||
"""
|
"""
|
||||||
Poll OpenLP to determine the current slide number and item name.
|
Poll OpenLP to determine the current slide number and item name.
|
||||||
@ -470,12 +493,20 @@ class HttpRouter(object):
|
|||||||
item['html'] = str(frame['html'])
|
item['html'] = str(frame['html'])
|
||||||
else:
|
else:
|
||||||
item['tag'] = str(index + 1)
|
item['tag'] = str(index + 1)
|
||||||
if current_item.name == 'presentations':
|
if current_item.is_capable(ItemCapabilities.HasDisplayTitle):
|
||||||
item['text'] = str(frame['displaytitle']) + '\n' + str(frame['notes'])
|
item['title'] = str(frame['displaytitle'])
|
||||||
else:
|
if current_item.is_capable(ItemCapabilities.HasNotes):
|
||||||
item['text'] = str(frame['title'])
|
item['notes'] = str(frame['notes'])
|
||||||
|
if current_item.is_capable(ItemCapabilities.HasThumbnails):
|
||||||
|
# if the file is under our app directory tree send the portion after the match
|
||||||
|
if frame['image'][0:len(AppLocation.get_data_path())] == AppLocation.get_data_path():
|
||||||
|
item['img'] = frame['image'][len(AppLocation.get_data_path()):]
|
||||||
|
#'data:image/png;base64,' + str(image_to_byte(resize_image(frame['image'],80,80)))
|
||||||
|
item['text'] = str(frame['title'])
|
||||||
item['html'] = str(frame['title'])
|
item['html'] = str(frame['title'])
|
||||||
item['selected'] = (self.live_controller.selected_row == index)
|
item['selected'] = (self.live_controller.selected_row == index)
|
||||||
|
if current_item.notes:
|
||||||
|
item['notes'] = item.get('notes','') + '\n' + current_item.notes
|
||||||
data.append(item)
|
data.append(item)
|
||||||
json_data = {'results': {'slides': data}}
|
json_data = {'results': {'slides': data}}
|
||||||
if current_item:
|
if current_item:
|
||||||
|
Loading…
Reference in New Issue
Block a user