forked from openlp/openlp
Added possible to point to a binary to use for pdf-processing.
This commit is contained in:
parent
308d5ed5ee
commit
d28d75a2ce
|
@ -249,8 +249,6 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
file_type = os.path.splitext(filename)[1][1:]
|
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
|
||||||
|
|
||||||
service_item.processor = self.display_type_combo_box.currentText()
|
|
||||||
|
|
||||||
if context == ServiceItemContext.Live and (file_type == u'pdf' or file_type == u'xps'):
|
if context == ServiceItemContext.Live and (file_type == u'pdf' or file_type == u'xps'):
|
||||||
service_item.add_capability(ItemCapabilities.CanMaintain)
|
service_item.add_capability(ItemCapabilities.CanMaintain)
|
||||||
|
@ -266,12 +264,11 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
(path, name) = os.path.split(filename)
|
(path, name) = os.path.split(filename)
|
||||||
service_item.title = name
|
service_item.title = name
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
if service_item.processor == self.Automatic:
|
processor = self.findControllerByType(filename)
|
||||||
service_item.processor = self.findControllerByType(filename)
|
if not processor:
|
||||||
if not service_item.processor:
|
return False
|
||||||
return False
|
controller = self.controllers[processor]
|
||||||
controller = self.controllers[service_item.processor]
|
service_item.processor = None
|
||||||
#service_item.processor = None
|
|
||||||
doc = controller.add_document(filename)
|
doc = controller.add_document(filename)
|
||||||
if doc.get_thumbnail_path(1, True) is None:
|
if doc.get_thumbnail_path(1, True) is None:
|
||||||
doc.load_presentation()
|
doc.load_presentation()
|
||||||
|
@ -300,6 +297,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
|
translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
service_item.processor = self.display_type_combo_box.currentText()
|
||||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||||
|
|
||||||
# Why the loop when we above return False if len(items) is > 1?
|
# Why the loop when we above return False if len(items) is > 1?
|
||||||
|
|
|
@ -324,7 +324,12 @@ class MessageListener(object):
|
||||||
controller = self.live_handler
|
controller = self.live_handler
|
||||||
else:
|
else:
|
||||||
controller = self.preview_handler
|
controller = self.preview_handler
|
||||||
controller.add_handler(self.controllers[self.handler], file, hide_mode, message[3])
|
# when presenting PDF, we're using the image presentation code,
|
||||||
|
# so handler & processor is set to None, and we skip adding the handler.
|
||||||
|
if self.handler == None:
|
||||||
|
self.controller = controller
|
||||||
|
else:
|
||||||
|
controller.add_handler(self.controllers[self.handler], file, hide_mode, message[3])
|
||||||
|
|
||||||
def slide(self, message):
|
def slide(self, message):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -31,16 +31,40 @@ import os
|
||||||
import logging
|
import logging
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
import re
|
import re
|
||||||
from subprocess import check_output, CalledProcessError
|
from subprocess import check_output, CalledProcessError, STDOUT
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.core.lib import ScreenList
|
from openlp.core.lib import ScreenList, Settings
|
||||||
from presentationcontroller import PresentationController, PresentationDocument
|
from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def check_binary(program_path):
|
||||||
|
"""
|
||||||
|
Function that checks whether a binary is either ghostscript or mudraw or neither.
|
||||||
|
"""
|
||||||
|
program_type = None
|
||||||
|
runlog = u''
|
||||||
|
try:
|
||||||
|
runlog = check_output([program_path, u'--help'], stderr=STDOUT)
|
||||||
|
except CalledProcessError as e:
|
||||||
|
runlog = e.output
|
||||||
|
except Exception:
|
||||||
|
runlog = u''
|
||||||
|
|
||||||
|
# Analyse the output to see it the program is mudraw, ghostscript or neither
|
||||||
|
for line in runlog.splitlines():
|
||||||
|
found_mudraw = re.search(u'usage: mudraw.*', line)
|
||||||
|
if found_mudraw:
|
||||||
|
program_type = u'mudraw'
|
||||||
|
break
|
||||||
|
found_gs = re.search(u'GPL Ghostscript.*', line)
|
||||||
|
if found_gs:
|
||||||
|
program_type = u'gs'
|
||||||
|
break
|
||||||
|
return program_type
|
||||||
|
|
||||||
class PdfController(PresentationController):
|
class PdfController(PresentationController):
|
||||||
"""
|
"""
|
||||||
|
@ -72,8 +96,20 @@ class PdfController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Check the viewer is installed.
|
Check the viewer is installed.
|
||||||
"""
|
"""
|
||||||
application_path = AppLocation.get_directory(AppLocation.AppDir)
|
|
||||||
log.debug(u'check_installed Pdf')
|
log.debug(u'check_installed Pdf')
|
||||||
|
# Use the user defined program if given
|
||||||
|
if (Settings().value(u'presentations/enable_given_pdf_program')):
|
||||||
|
given_pdf_program = Settings().value(u'presentations/given_pdf_program')
|
||||||
|
type = check_binary(given_pdf_program)
|
||||||
|
if type == u'gs':
|
||||||
|
self.gsbin = given_pdf_program
|
||||||
|
return True
|
||||||
|
elif type == u'mudraw':
|
||||||
|
self.mudrawbin = given_pdf_program
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Fallback to autodetection
|
||||||
|
application_path = AppLocation.get_directory(AppLocation.AppDir)
|
||||||
if os.name != u'nt':
|
if os.name != u'nt':
|
||||||
# First try to find mupdf
|
# First try to find mupdf
|
||||||
try:
|
try:
|
||||||
|
@ -153,7 +189,12 @@ quit \n\
|
||||||
tmpfile.close()
|
tmpfile.close()
|
||||||
|
|
||||||
# Run the script on the pdf to get the size
|
# Run the script on the pdf to get the size
|
||||||
runlog = check_output([self.controller.gsbin, u'-dNOPAUSE', u'-dNODISPLAY', u'-dBATCH', u'-sFile=' + self.filepath, tmpfile.name])
|
runlog = []
|
||||||
|
try:
|
||||||
|
runlog = check_output([self.controller.gsbin, u'-dNOPAUSE', u'-dNODISPLAY', u'-dBATCH', u'-sFile=' + self.filepath, tmpfile.name])
|
||||||
|
except CalledProcessError as e:
|
||||||
|
log.debug(u' '.join(e.cmd))
|
||||||
|
log.debug(e.output)
|
||||||
os.unlink(tmpfile.name)
|
os.unlink(tmpfile.name)
|
||||||
|
|
||||||
# Extract the pdf resolution from output, the format is " Size: x: <width>, y: <height>"
|
# Extract the pdf resolution from output, the format is " Size: x: <width>, y: <height>"
|
||||||
|
|
|
@ -29,8 +29,9 @@
|
||||||
|
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Settings, SettingsTab, UiStrings, translate
|
from openlp.core.lib import Settings, SettingsTab, UiStrings, translate, build_icon
|
||||||
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
|
from pdfcontroller import check_binary
|
||||||
|
|
||||||
class PresentationTab(SettingsTab):
|
class PresentationTab(SettingsTab):
|
||||||
"""
|
"""
|
||||||
|
@ -63,6 +64,7 @@ class PresentationTab(SettingsTab):
|
||||||
self.presenter_check_boxes[controller.name] = checkbox
|
self.presenter_check_boxes[controller.name] = checkbox
|
||||||
self.controllers_layout.addWidget(checkbox)
|
self.controllers_layout.addWidget(checkbox)
|
||||||
self.left_layout.addWidget(self.controllers_group_box)
|
self.left_layout.addWidget(self.controllers_group_box)
|
||||||
|
# Advanced
|
||||||
self.advanced_group_box = QtGui.QGroupBox(self.left_column)
|
self.advanced_group_box = QtGui.QGroupBox(self.left_column)
|
||||||
self.advanced_group_box.setObjectName(u'advanced_group_box')
|
self.advanced_group_box.setObjectName(u'advanced_group_box')
|
||||||
self.advanced_layout = QtGui.QVBoxLayout(self.advanced_group_box)
|
self.advanced_layout = QtGui.QVBoxLayout(self.advanced_group_box)
|
||||||
|
@ -70,7 +72,33 @@ class PresentationTab(SettingsTab):
|
||||||
self.override_app_check_box = QtGui.QCheckBox(self.advanced_group_box)
|
self.override_app_check_box = QtGui.QCheckBox(self.advanced_group_box)
|
||||||
self.override_app_check_box.setObjectName(u'override_app_check_box')
|
self.override_app_check_box.setObjectName(u'override_app_check_box')
|
||||||
self.advanced_layout.addWidget(self.override_app_check_box)
|
self.advanced_layout.addWidget(self.override_app_check_box)
|
||||||
|
|
||||||
|
# Pdf options
|
||||||
|
self.pdf_group_box = QtGui.QGroupBox(self.left_column)
|
||||||
|
self.pdf_group_box.setObjectName(u'pdf_group_box')
|
||||||
|
self.pdf_layout = QtGui.QFormLayout(self.pdf_group_box)
|
||||||
|
self.pdf_layout.setObjectName(u'pdf_layout')
|
||||||
|
self.pdf_program_check_box = QtGui.QCheckBox(self.pdf_group_box)
|
||||||
|
self.pdf_program_check_box.setObjectName(u'pdf_program_check_box')
|
||||||
|
self.pdf_layout.addWidget(self.pdf_program_check_box)
|
||||||
|
self.pdf_program_path_layout = QtGui.QHBoxLayout()
|
||||||
|
self.pdf_program_path_layout.setObjectName(u'pdf_program_path_layout')
|
||||||
|
self.pdf_program_path = QtGui.QLineEdit(self.pdf_group_box)
|
||||||
|
self.pdf_program_path.setObjectName(u'pdf_program_path')
|
||||||
|
self.pdf_program_path.setReadOnly(True)
|
||||||
|
self.pdf_program_path.setPalette(self.get_grey_text_palette(True))
|
||||||
|
self.pdf_program_path_layout.addWidget(self.pdf_program_path)
|
||||||
|
self.pdf_program_browse_button = QtGui.QToolButton(self.pdf_group_box)
|
||||||
|
self.pdf_program_browse_button.setObjectName(u'pdf_program_browse_button')
|
||||||
|
self.pdf_program_browse_button.setIcon(build_icon(u':/general/general_open.png'))
|
||||||
|
self.pdf_program_browse_button.setEnabled(False)
|
||||||
|
self.pdf_program_path_layout.addWidget(self.pdf_program_browse_button)
|
||||||
|
self.pdf_layout.addRow(self.pdf_program_path_layout)
|
||||||
|
self.pdf_program_path.editingFinished.connect(self.on_pdf_program_path_edit_finished)
|
||||||
|
self.pdf_program_browse_button.clicked.connect(self.on_pdf_program_browse_button_clicked)
|
||||||
|
self.pdf_program_check_box.clicked.connect(self.on_pdf_program_check_box_clicked)
|
||||||
self.left_layout.addWidget(self.advanced_group_box)
|
self.left_layout.addWidget(self.advanced_group_box)
|
||||||
|
self.left_layout.addWidget(self.pdf_group_box)
|
||||||
self.left_layout.addStretch()
|
self.left_layout.addStretch()
|
||||||
self.right_layout.addStretch()
|
self.right_layout.addStretch()
|
||||||
|
|
||||||
|
@ -84,8 +112,12 @@ class PresentationTab(SettingsTab):
|
||||||
checkbox = self.presenter_check_boxes[controller.name]
|
checkbox = self.presenter_check_boxes[controller.name]
|
||||||
self.set_controller_text(checkbox, controller)
|
self.set_controller_text(checkbox, controller)
|
||||||
self.advanced_group_box.setTitle(UiStrings().Advanced)
|
self.advanced_group_box.setTitle(UiStrings().Advanced)
|
||||||
|
self.pdf_group_box.setTitle(translate('PresentationPlugin.PresentationTab', 'PDF options'))
|
||||||
self.override_app_check_box.setText(
|
self.override_app_check_box.setText(
|
||||||
translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
|
translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
|
||||||
|
self.pdf_program_check_box.setText(
|
||||||
|
translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:'))
|
||||||
|
|
||||||
|
|
||||||
def set_controller_text(self, checkbox, controller):
|
def set_controller_text(self, checkbox, controller):
|
||||||
if checkbox.isEnabled():
|
if checkbox.isEnabled():
|
||||||
|
@ -102,6 +134,15 @@ class PresentationTab(SettingsTab):
|
||||||
checkbox = self.presenter_check_boxes[controller.name]
|
checkbox = self.presenter_check_boxes[controller.name]
|
||||||
checkbox.setChecked(Settings().value(self.settings_section + u'/' + controller.name))
|
checkbox.setChecked(Settings().value(self.settings_section + u'/' + controller.name))
|
||||||
self.override_app_check_box.setChecked(Settings().value(self.settings_section + u'/override app'))
|
self.override_app_check_box.setChecked(Settings().value(self.settings_section + u'/override app'))
|
||||||
|
# load pdf-program settings
|
||||||
|
enable_given_pdf_program = Settings().value(self.settings_section + u'/enable_given_pdf_program')
|
||||||
|
self.pdf_program_check_box.setChecked(enable_given_pdf_program)
|
||||||
|
self.pdf_program_path.setReadOnly(not enable_given_pdf_program)
|
||||||
|
self.pdf_program_path.setPalette(self.get_grey_text_palette(not enable_given_pdf_program))
|
||||||
|
self.pdf_program_browse_button.setEnabled(enable_given_pdf_program)
|
||||||
|
pdf_program = Settings().value(self.settings_section + u'/given_pdf_program')
|
||||||
|
if pdf_program:
|
||||||
|
self.pdf_program_path.setText(pdf_program)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
|
@ -127,10 +168,25 @@ class PresentationTab(SettingsTab):
|
||||||
if Settings().value(setting_key) != self.override_app_check_box.checkState():
|
if Settings().value(setting_key) != self.override_app_check_box.checkState():
|
||||||
Settings().setValue(setting_key, self.override_app_check_box.checkState())
|
Settings().setValue(setting_key, self.override_app_check_box.checkState())
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
# Save pdf-settings
|
||||||
|
pdf_program = self.pdf_program_path.text()
|
||||||
|
enable_given_pdf_program = self.pdf_program_check_box.checkState()
|
||||||
|
# If the given program is blank disable using the program
|
||||||
|
if pdf_program == u'':
|
||||||
|
enable_given_pdf_program = 0
|
||||||
|
if pdf_program != Settings().value(self.settings_section + u'/given_pdf_program'):
|
||||||
|
Settings().setValue(self.settings_section + u'/given_pdf_program', pdf_program)
|
||||||
|
changed = True
|
||||||
|
if enable_given_pdf_program != Settings().value(self.settings_section + u'/enable_given_pdf_program'):
|
||||||
|
Settings().setValue(self.settings_section + u'/enable_given_pdf_program', enable_given_pdf_program)
|
||||||
|
changed = True
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
self.settings_form.register_post_process(u'mediaitem_suffix_reset')
|
self.settings_form.register_post_process(u'mediaitem_suffix_reset')
|
||||||
self.settings_form.register_post_process(u'mediaitem_presentation_rebuild')
|
self.settings_form.register_post_process(u'mediaitem_presentation_rebuild')
|
||||||
self.settings_form.register_post_process(u'mediaitem_suffixes')
|
self.settings_form.register_post_process(u'mediaitem_suffixes')
|
||||||
|
|
||||||
|
|
||||||
def tab_visible(self):
|
def tab_visible(self):
|
||||||
"""
|
"""
|
||||||
|
@ -142,3 +198,44 @@ class PresentationTab(SettingsTab):
|
||||||
checkbox = self.presenter_check_boxes[controller.name]
|
checkbox = self.presenter_check_boxes[controller.name]
|
||||||
checkbox.setEnabled(controller.is_available())
|
checkbox.setEnabled(controller.is_available())
|
||||||
self.set_controller_text(checkbox, controller)
|
self.set_controller_text(checkbox, controller)
|
||||||
|
|
||||||
|
def on_pdf_program_path_edit_finished(self):
|
||||||
|
"""
|
||||||
|
After selecting/typing in a program it is validated that it is a actually ghostscript or mudraw
|
||||||
|
"""
|
||||||
|
type = None
|
||||||
|
if self.pdf_program_path.text() != u'':
|
||||||
|
type = check_binary(self.pdf_program_path.text())
|
||||||
|
if not type:
|
||||||
|
critical_error_message_box(UiStrings().Error,
|
||||||
|
translate('PresentationPlugin.PresentationTab', 'The program is not ghostscript or mudraw which is required.'))
|
||||||
|
self.pdf_program_path.setFocus()
|
||||||
|
|
||||||
|
def on_pdf_program_browse_button_clicked(self):
|
||||||
|
"""
|
||||||
|
Select the mudraw or ghostscript binary that should be used.
|
||||||
|
"""
|
||||||
|
filename = QtGui.QFileDialog.getOpenFileName(self, translate('PresentationPlugin.PresentationTab', 'Select mudraw or ghostscript binary.'))
|
||||||
|
if filename:
|
||||||
|
self.pdf_program_path.setText(filename)
|
||||||
|
self.pdf_program_path.setFocus()
|
||||||
|
|
||||||
|
def on_pdf_program_check_box_clicked(self, checked):
|
||||||
|
"""
|
||||||
|
When checkbox for manual entering pdf-program is clicked,
|
||||||
|
enable or disable the textbox for the programpath and the browse-button.
|
||||||
|
"""
|
||||||
|
self.pdf_program_path.setReadOnly(not checked)
|
||||||
|
self.pdf_program_path.setPalette(self.get_grey_text_palette(not checked))
|
||||||
|
self.pdf_program_browse_button.setEnabled(checked)
|
||||||
|
|
||||||
|
def get_grey_text_palette(self, greyed):
|
||||||
|
"""
|
||||||
|
Returns a QPalette with greyed out text as used for placeholderText.
|
||||||
|
"""
|
||||||
|
palette = QtGui.QPalette()
|
||||||
|
color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Text)
|
||||||
|
if greyed:
|
||||||
|
color.setAlpha(128)
|
||||||
|
palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
|
||||||
|
return palette
|
||||||
|
|
|
@ -45,6 +45,8 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
__default_settings__ = {
|
__default_settings__ = {
|
||||||
u'presentations/override app': QtCore.Qt.Unchecked,
|
u'presentations/override app': QtCore.Qt.Unchecked,
|
||||||
|
u'presentations/enable_given_pdf_program': QtCore.Qt.Unchecked,
|
||||||
|
u'presentations/given_pdf_program': u'',
|
||||||
u'presentations/Impress': QtCore.Qt.Checked,
|
u'presentations/Impress': QtCore.Qt.Checked,
|
||||||
u'presentations/Powerpoint': QtCore.Qt.Checked,
|
u'presentations/Powerpoint': QtCore.Qt.Checked,
|
||||||
u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
||||||
|
|
Loading…
Reference in New Issue