forked from openlp/openlp
Instead of using a special PDF-player, now we present the images from PDF using the image-presentation features.
This commit is contained in:
parent
fa537260f6
commit
308d5ed5ee
|
@ -244,45 +244,100 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
items = self.list_view.selectedItems()
|
items = self.list_view.selectedItems()
|
||||||
if len(items) > 1:
|
if len(items) > 1:
|
||||||
return False
|
return False
|
||||||
service_item.processor = self.display_type_combo_box.currentText()
|
|
||||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
filename = items[0].data(QtCore.Qt.UserRole)
|
||||||
|
file_type = os.path.splitext(filename)[1][1:]
|
||||||
if not self.display_type_combo_box.currentText():
|
if not self.display_type_combo_box.currentText():
|
||||||
return False
|
return False
|
||||||
for bitem in items:
|
|
||||||
filename = bitem.data(QtCore.Qt.UserRole)
|
service_item.processor = self.display_type_combo_box.currentText()
|
||||||
(path, name) = os.path.split(filename)
|
|
||||||
service_item.title = name
|
if context == ServiceItemContext.Live and (file_type == u'pdf' or file_type == u'xps'):
|
||||||
if os.path.exists(filename):
|
service_item.add_capability(ItemCapabilities.CanMaintain)
|
||||||
if service_item.processor == self.Automatic:
|
service_item.add_capability(ItemCapabilities.CanPreview)
|
||||||
service_item.processor = self.findControllerByType(filename)
|
service_item.add_capability(ItemCapabilities.CanLoop)
|
||||||
if not service_item.processor:
|
service_item.add_capability(ItemCapabilities.CanAppend)
|
||||||
|
# force a nonexistent theme
|
||||||
|
service_item.theme = -1
|
||||||
|
|
||||||
|
# Why the loop when we above return False if len(items) is > 1?
|
||||||
|
for bitem in items:
|
||||||
|
filename = bitem.data(QtCore.Qt.UserRole)
|
||||||
|
(path, name) = os.path.split(filename)
|
||||||
|
service_item.title = name
|
||||||
|
if os.path.exists(filename):
|
||||||
|
if service_item.processor == self.Automatic:
|
||||||
|
service_item.processor = self.findControllerByType(filename)
|
||||||
|
if not service_item.processor:
|
||||||
|
return False
|
||||||
|
controller = self.controllers[service_item.processor]
|
||||||
|
#service_item.processor = None
|
||||||
|
doc = controller.add_document(filename)
|
||||||
|
if doc.get_thumbnail_path(1, True) is None:
|
||||||
|
doc.load_presentation()
|
||||||
|
i = 1
|
||||||
|
imagefile = u'mainslide%03d.png' % i
|
||||||
|
img = os.path.join(doc.get_temp_folder(), imagefile)
|
||||||
|
if os.path.isfile(img):
|
||||||
|
while os.path.isfile(img):
|
||||||
|
service_item.add_from_image(img, name)
|
||||||
|
i += 1
|
||||||
|
imagefile = u'mainslide%03d.png' % i
|
||||||
|
img = os.path.join(doc.get_temp_folder(), imagefile)
|
||||||
|
doc.close_presentation()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# File is no longer present
|
||||||
|
if not remote:
|
||||||
|
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||||
|
translate('PresentationPlugin.MediaItem',
|
||||||
|
'The presentation %s is incomplete, please reload.') % filename)
|
||||||
return False
|
return False
|
||||||
controller = self.controllers[service_item.processor]
|
|
||||||
doc = controller.add_document(filename)
|
|
||||||
if doc.get_thumbnail_path(1, True) is None:
|
|
||||||
doc.load_presentation()
|
|
||||||
i = 1
|
|
||||||
img = doc.get_thumbnail_path(i, True)
|
|
||||||
if img:
|
|
||||||
while img:
|
|
||||||
service_item.add_from_command(path, name, img)
|
|
||||||
i += 1
|
|
||||||
img = doc.get_thumbnail_path(i, True)
|
|
||||||
doc.close_presentation()
|
|
||||||
return True
|
|
||||||
else:
|
else:
|
||||||
# File is no longer present
|
# File is no longer present
|
||||||
if not remote:
|
if not remote:
|
||||||
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||||
translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
|
||||||
'The presentation %s is incomplete, please reload.') % filename)
|
return False
|
||||||
|
else:
|
||||||
|
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||||
|
|
||||||
|
# Why the loop when we above return False if len(items) is > 1?
|
||||||
|
for bitem in items:
|
||||||
|
filename = bitem.data(QtCore.Qt.UserRole)
|
||||||
|
(path, name) = os.path.split(filename)
|
||||||
|
service_item.title = name
|
||||||
|
if os.path.exists(filename):
|
||||||
|
if service_item.processor == self.Automatic:
|
||||||
|
service_item.processor = self.findControllerByType(filename)
|
||||||
|
if not service_item.processor:
|
||||||
|
return False
|
||||||
|
controller = self.controllers[service_item.processor]
|
||||||
|
doc = controller.add_document(filename)
|
||||||
|
if doc.get_thumbnail_path(1, True) is None:
|
||||||
|
doc.load_presentation()
|
||||||
|
i = 1
|
||||||
|
img = doc.get_thumbnail_path(i, True)
|
||||||
|
if img:
|
||||||
|
while img:
|
||||||
|
service_item.add_from_command(path, name, img)
|
||||||
|
i += 1
|
||||||
|
img = doc.get_thumbnail_path(i, True)
|
||||||
|
doc.close_presentation()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# File is no longer present
|
||||||
|
if not remote:
|
||||||
|
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||||
|
translate('PresentationPlugin.MediaItem',
|
||||||
|
'The presentation %s is incomplete, please reload.') % filename)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# File is no longer present
|
||||||
|
if not remote:
|
||||||
|
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||||
|
translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
|
||||||
return False
|
return False
|
||||||
else:
|
|
||||||
# File is no longer present
|
|
||||||
if not remote:
|
|
||||||
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
|
||||||
translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def findControllerByType(self, filename):
|
def findControllerByType(self, filename):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -60,7 +60,6 @@ class PdfController(PresentationController):
|
||||||
self.gsbin = u''
|
self.gsbin = u''
|
||||||
if self.check_installed() and self.mudrawbin != u'':
|
if self.check_installed() and self.mudrawbin != u'':
|
||||||
self.also_supports = [u'xps']
|
self.also_supports = [u'xps']
|
||||||
self.viewer = None
|
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
|
@ -74,7 +73,6 @@ class PdfController(PresentationController):
|
||||||
Check the viewer is installed.
|
Check the viewer is installed.
|
||||||
"""
|
"""
|
||||||
application_path = AppLocation.get_directory(AppLocation.AppDir)
|
application_path = AppLocation.get_directory(AppLocation.AppDir)
|
||||||
print application_path
|
|
||||||
log.debug(u'check_installed Pdf')
|
log.debug(u'check_installed Pdf')
|
||||||
if os.name != u'nt':
|
if os.name != u'nt':
|
||||||
# First try to find mupdf
|
# First try to find mupdf
|
||||||
|
@ -105,30 +103,19 @@ class PdfController(PresentationController):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def start_process(self):
|
|
||||||
log.debug(u'start_process pdf')
|
|
||||||
# Setup viewer
|
|
||||||
try:
|
|
||||||
size = ScreenList().current[u'size']
|
|
||||||
self.viewer = PdfViewer(size)
|
|
||||||
except Exception as e:
|
|
||||||
log.debug(e)
|
|
||||||
|
|
||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
"""
|
"""
|
||||||
Called at system exit to clean up any running presentations
|
Called at system exit to clean up any running presentations
|
||||||
"""
|
"""
|
||||||
log.debug(u'Kill pdfviewer')
|
log.debug(u'Kill pdfviewer')
|
||||||
self.viewer.close()
|
|
||||||
while self.docs:
|
while self.docs:
|
||||||
self.docs[0].close_presentation()
|
self.docs[0].close_presentation()
|
||||||
|
|
||||||
|
|
||||||
class PdfDocument(PresentationDocument):
|
class PdfDocument(PresentationDocument):
|
||||||
"""
|
"""
|
||||||
Class which holds information and controls a single presentation.
|
Class which holds information of a single presentation.
|
||||||
"""
|
"""
|
||||||
def __init__(self, controller, presentation):
|
def __init__(self, controller, presentation):
|
||||||
"""
|
"""
|
||||||
|
@ -142,10 +129,12 @@ class PdfDocument(PresentationDocument):
|
||||||
self.image_files = []
|
self.image_files = []
|
||||||
self.num_pages = -1
|
self.num_pages = -1
|
||||||
|
|
||||||
# Only used when using ghostscript
|
|
||||||
# Ghostscript can't scale automaticly while keeping aspect like mupdf, so we need
|
|
||||||
# to get the ratio bewteen the screen size and the PDF to scale
|
|
||||||
def gs_get_resolution(self, size):
|
def gs_get_resolution(self, size):
|
||||||
|
"""
|
||||||
|
Only used when using ghostscript
|
||||||
|
Ghostscript can't scale automaticly while keeping aspect like mupdf, so we need
|
||||||
|
to get the ratio bewteen the screen size and the PDF to scale
|
||||||
|
"""
|
||||||
# Use a postscript script to get size of the pdf. It is assumed that all pages have same size
|
# Use a postscript script to get size of the pdf. It is assumed that all pages have same size
|
||||||
postscript = u'%!PS \n\
|
postscript = u'%!PS \n\
|
||||||
() = \n\
|
() = \n\
|
||||||
|
@ -198,11 +187,11 @@ quit \n\
|
||||||
log.debug(u'load_presentation pdf')
|
log.debug(u'load_presentation pdf')
|
||||||
|
|
||||||
# Check if the images has already been created, and if yes load them
|
# Check if the images has already been created, and if yes load them
|
||||||
if os.path.isfile(self.get_temp_folder() + u'/mainslide001.png'):
|
if os.path.isfile(os.path.join(self.get_temp_folder(), u'mainslide001.png')):
|
||||||
created_files = sorted(os.listdir(self.get_temp_folder()))
|
created_files = sorted(os.listdir(self.get_temp_folder()))
|
||||||
for fn in created_files:
|
for fn in created_files:
|
||||||
if os.path.isfile(self.get_temp_folder() + u'/' + fn):
|
if os.path.isfile(os.path.join(self.get_temp_folder(), fn)):
|
||||||
self.image_files.append(self.get_temp_folder()+ u'/' + fn)
|
self.image_files.append(os.path.join(self.get_temp_folder(), fn))
|
||||||
self.num_pages = len(self.image_files)
|
self.num_pages = len(self.image_files)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -213,14 +202,14 @@ quit \n\
|
||||||
if not os.path.isdir(self.get_temp_folder()):
|
if not os.path.isdir(self.get_temp_folder()):
|
||||||
os.makedirs(self.get_temp_folder())
|
os.makedirs(self.get_temp_folder())
|
||||||
if self.controller.mudrawbin != u'':
|
if self.controller.mudrawbin != u'':
|
||||||
runlog = check_output([self.controller.mudrawbin, u'-w', str(size.right()), u'-h', str(size.bottom()), u'-o', self.get_temp_folder() + u'/mainslide%03d.png', self.filepath])
|
runlog = check_output([self.controller.mudrawbin, u'-w', str(size.right()), u'-h', str(size.bottom()), u'-o', os.path.join(self.get_temp_folder(), u'mainslide%03d.png'), self.filepath])
|
||||||
elif self.controller.gsbin != u'':
|
elif self.controller.gsbin != u'':
|
||||||
resolution = self.gs_get_resolution(size)
|
resolution = self.gs_get_resolution(size)
|
||||||
runlog = check_output([self.controller.gsbin, u'-dSAFER', u'-dNOPAUSE', u'-dBATCH', u'-sDEVICE=png16m', u'-r' + str(resolution), u'-dTextAlphaBits=4', u'-dGraphicsAlphaBits=4', u'-sOutputFile=' + self.get_temp_folder() + u'/mainslide%03d.png', self.filepath])
|
runlog = check_output([self.controller.gsbin, u'-dSAFER', u'-dNOPAUSE', u'-dBATCH', u'-sDEVICE=png16m', u'-r' + str(resolution), u'-dTextAlphaBits=4', u'-dGraphicsAlphaBits=4', u'-sOutputFile=' + os.path.join(self.get_temp_folder(), u'mainslide%03d.png'), self.filepath])
|
||||||
created_files = sorted(os.listdir(self.get_temp_folder()))
|
created_files = sorted(os.listdir(self.get_temp_folder()))
|
||||||
for fn in created_files:
|
for fn in created_files:
|
||||||
if os.path.isfile(self.get_temp_folder() + u'/' + fn):
|
if os.path.isfile(os.path.join(self.get_temp_folder(), fn)):
|
||||||
self.image_files.append(self.get_temp_folder()+ u'/' + fn)
|
self.image_files.append(os.path.join(self.get_temp_folder(), fn))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug(e)
|
log.debug(e)
|
||||||
log.debug(runlog)
|
log.debug(runlog)
|
||||||
|
@ -253,7 +242,6 @@ quit \n\
|
||||||
"""
|
"""
|
||||||
log.debug(u'close_presentation pdf')
|
log.debug(u'close_presentation pdf')
|
||||||
self.controller.remove_doc(self)
|
self.controller.remove_doc(self)
|
||||||
# TODO
|
|
||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
"""
|
"""
|
||||||
|
@ -271,174 +259,3 @@ quit \n\
|
||||||
log.debug(u'is_active pdf')
|
log.debug(u'is_active pdf')
|
||||||
return self.is_loaded() and not self.hidden
|
return self.is_loaded() and not self.hidden
|
||||||
|
|
||||||
def blank_screen(self):
|
|
||||||
"""
|
|
||||||
Blanks the screen.
|
|
||||||
"""
|
|
||||||
log.debug(u'blank_screen pdf')
|
|
||||||
self.blanked = True
|
|
||||||
self.controller.viewer.blank()
|
|
||||||
|
|
||||||
def unblank_screen(self):
|
|
||||||
"""
|
|
||||||
Unblanks (restores) the presentation.
|
|
||||||
"""
|
|
||||||
log.debug(u'unblank_screen pdf')
|
|
||||||
self.blanked = False
|
|
||||||
self.controller.viewer.unblank()
|
|
||||||
|
|
||||||
def is_blank(self):
|
|
||||||
"""
|
|
||||||
Returns true if screen is blank.
|
|
||||||
"""
|
|
||||||
log.debug(u'is blank pdf')
|
|
||||||
return self.blanked
|
|
||||||
|
|
||||||
def stop_presentation(self):
|
|
||||||
"""
|
|
||||||
Stops the current presentation and hides the output.
|
|
||||||
"""
|
|
||||||
log.debug(u'stop_presentation pdf')
|
|
||||||
self.hidden = True
|
|
||||||
self.controller.viewer.stop()
|
|
||||||
|
|
||||||
def start_presentation(self):
|
|
||||||
"""
|
|
||||||
Starts a presentation from the beginning.
|
|
||||||
"""
|
|
||||||
log.debug(u'start_presentation pdf')
|
|
||||||
if self.hidden:
|
|
||||||
self.hidden = False
|
|
||||||
self.controller.viewer.start(self.image_files)
|
|
||||||
|
|
||||||
def get_slide_number(self):
|
|
||||||
"""
|
|
||||||
Return the current slide number on the screen, from 1.
|
|
||||||
"""
|
|
||||||
log.debug(u'get_slide_number pdf')
|
|
||||||
return self.controller.viewer.get_current_page() + 1
|
|
||||||
|
|
||||||
def get_slide_count(self):
|
|
||||||
"""
|
|
||||||
Returns total number of slides.
|
|
||||||
"""
|
|
||||||
log.debug(u'get_slide_count pdf')
|
|
||||||
return self.num_pages
|
|
||||||
|
|
||||||
def goto_slide(self, slideno):
|
|
||||||
"""
|
|
||||||
Moves to a specific slide in the presentation.
|
|
||||||
"""
|
|
||||||
log.debug(u'goto_slide pdf' + str(slideno))
|
|
||||||
self.controller.viewer.show_page(slideno - 1)
|
|
||||||
# TODO
|
|
||||||
|
|
||||||
def next_step(self):
|
|
||||||
"""
|
|
||||||
Triggers the next effect of slide on the running presentation.
|
|
||||||
"""
|
|
||||||
log.debug(u'next_step pdf')
|
|
||||||
self.controller.viewer.next_page()
|
|
||||||
|
|
||||||
def previous_step(self):
|
|
||||||
"""
|
|
||||||
Triggers the previous slide on the running presentation.
|
|
||||||
"""
|
|
||||||
log.debug(u'previous_step pdf')
|
|
||||||
self.controller.viewer.previous_page()
|
|
||||||
|
|
||||||
|
|
||||||
class PdfViewer(QtGui.QWidget):
|
|
||||||
def __init__(self, rect):
|
|
||||||
log.debug(u'initialised pdf viewer')
|
|
||||||
QtGui.QWidget.__init__(self, None)
|
|
||||||
self.setWindowTitle("PDF Viewer")
|
|
||||||
p = QtGui.QPalette()
|
|
||||||
p.setColor(QtGui.QPalette.Background, QtCore.Qt.black);
|
|
||||||
self.setPalette(p)
|
|
||||||
self.setGeometry(rect) # QtGui.QApplication.desktop().screenGeometry())
|
|
||||||
self.hide()
|
|
||||||
self.num_pages = 0
|
|
||||||
self.pdf_images = []
|
|
||||||
self.image_files = []
|
|
||||||
self.is_blanked = False
|
|
||||||
self.current_page = 0
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
if event.key() == QtCore.Qt.Key_Down:
|
|
||||||
self.next_page()
|
|
||||||
elif event.key() == QtCore.Qt.Key_Up:
|
|
||||||
self.previous_page()
|
|
||||||
elif event.key() == QtCore.Qt.Key_Escape:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def paintEvent(self, event):
|
|
||||||
if self.is_blanked:
|
|
||||||
return
|
|
||||||
img = self.get_image(self.current_page)
|
|
||||||
if img is None:
|
|
||||||
return
|
|
||||||
x = (self.frameSize().width() - img.width()) / 2
|
|
||||||
y = (self.frameSize().height() - img.height()) / 2
|
|
||||||
painter = QtGui.QPainter(self)
|
|
||||||
painter.drawImage(x, y, img, 0, 0, 0, 0)
|
|
||||||
|
|
||||||
def display(self):
|
|
||||||
self.update()
|
|
||||||
self.cache_image(self.current_page + 1)
|
|
||||||
|
|
||||||
def start(self, images):
|
|
||||||
log.debug(u'start pdfviewer')
|
|
||||||
self.image_files = images
|
|
||||||
self.num_pages = len(self.image_files)
|
|
||||||
self.pdf_images = [None for i in range(self.num_pages)]
|
|
||||||
self.showFullScreen()
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
log.debug(u'stop pdfviewer')
|
|
||||||
self.hide()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
log.debug(u'close pdfviewer')
|
|
||||||
self.stop()
|
|
||||||
self.pdf_images = None
|
|
||||||
self.image_files = None
|
|
||||||
|
|
||||||
def blank(self):
|
|
||||||
self.is_blanked = True
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def unblank(self):
|
|
||||||
self.is_blanked = False
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def next_page(self):
|
|
||||||
if self.current_page + 1 < self.num_pages:
|
|
||||||
self.current_page += 1
|
|
||||||
self.display()
|
|
||||||
|
|
||||||
def previous_page(self):
|
|
||||||
if self.current_page > 0:
|
|
||||||
self.current_page -= 1
|
|
||||||
self.display()
|
|
||||||
|
|
||||||
def show_page(self, idx):
|
|
||||||
if idx < self.num_pages:
|
|
||||||
self.current_page = idx
|
|
||||||
self.display()
|
|
||||||
|
|
||||||
def cache_image(self, idx):
|
|
||||||
if idx >= self.num_pages:
|
|
||||||
return
|
|
||||||
if self.image_files[idx] is None:
|
|
||||||
return
|
|
||||||
img = QtGui.QImage(self.image_files[idx])
|
|
||||||
self.pdf_images[idx] = img
|
|
||||||
|
|
||||||
def get_image(self, idx):
|
|
||||||
self.cache_image(idx)
|
|
||||||
return self.pdf_images[idx]
|
|
||||||
|
|
||||||
def get_current_page(self):
|
|
||||||
return self.current_page
|
|
||||||
|
|
Loading…
Reference in New Issue