diff --git a/openlp/plugins/presentations/lib/__init__.py b/openlp/plugins/presentations/lib/__init__.py index 61aa34228..d042a10e4 100644 --- a/openlp/plugins/presentations/lib/__init__.py +++ b/openlp/plugins/presentations/lib/__init__.py @@ -23,9 +23,6 @@ ############################################################################### from presentationcontroller import PresentationController -from impresscontroller import ImpressController -from powerpointcontroller import PowerpointController -from pptviewcontroller import PptviewController from messagelistener import MessageListener from mediaitem import PresentationMediaItem from presentationtab import PresentationTab diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 869fd5fb2..ff8d13729 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -34,11 +34,8 @@ if os.name == u'nt': else: import uno -from PyQt4 import QtCore - from presentationcontroller import PresentationController - class ImpressController(PresentationController): """ Class to control interactions with Impress presentations. @@ -47,6 +44,7 @@ class ImpressController(PresentationController): """ global log log = logging.getLogger(u'ImpressController') + log.info(u'loaded') def __init__(self, plugin): """ @@ -59,16 +57,17 @@ class ImpressController(PresentationController): self.presentation = None self.controller = None - def is_available(self): + def check_available(self): """ - PPT Viewer is able to run on this machine + Impress is able to run on this machine """ - log.debug(u'is_available') - try: - self.start_process() + log.debug(u'check_available') + if os.name == u'nt': + return self.get_com_servicemanager() is not None + else: + # If not windows, and we've got this far then probably + # installed else the import uno would likely have failed return True - except: - return False def start_process(self): """ @@ -148,13 +147,21 @@ class ImpressController(PresentationController): def get_com_desktop(self): log.debug(u'getCOMDesktop') try: - smgr = Dispatch("com.sun.star.ServiceManager") + smgr = self.get_com_servicemanager() desktop = smgr.createInstance( "com.sun.star.frame.Desktop") return desktop except: log.exception(u'Failed to get COM desktop') return None + def get_com_servicemanager(self): + log.debug(u'get_com_servicemanager') + try: + return Dispatch("com.sun.star.ServiceManager") + except: + log.exception(u'Failed to get COM service manager') + return None + def close_presentation(self): """ Close presentation and clean up objects diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index be308f1d9..356cf3acc 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -94,7 +94,8 @@ class PresentationMediaItem(MediaManagerItem): self.loadList(list) for item in self.controllers: #load the drop down selection - self.DisplayTypeComboBox.addItem(item) + if self.controllers[item].enabled: + self.DisplayTypeComboBox.addItem(item) def loadList(self, list): for file in list: diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index cac1b7008..0f13493e5 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -27,6 +27,7 @@ import logging if os.name == u'nt': from win32com.client import Dispatch + import _winreg from presentationcontroller import PresentationController @@ -41,7 +42,8 @@ class PowerpointController(PresentationController): """ global log log = logging.getLogger(u'PowerpointController') - + log.info(u'loaded') + def __init__(self, plugin): """ Initialise the class @@ -51,18 +53,18 @@ class PowerpointController(PresentationController): self.process = None self.presentation = None - def is_available(self): + def check_available(self): """ PowerPoint is able to run on this machine """ - log.debug(u'is_available') - if os.name != u'nt': - return False - try: - self.start_process() - return True - except: - return False + log.debug(u'check_available') + if os.name == u'nt': + try: + _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close() + return True + except: + pass + return False if os.name == u'nt': def start_process(self): @@ -83,6 +85,9 @@ class PowerpointController(PresentationController): return False def kill(self): + """ + Called at system exit to clean up any running presentations + """ self.process.Quit() self.process = None diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 97c0ceb5d..3622085cd 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -39,37 +39,50 @@ class PptviewController(PresentationController): """ global log log = logging.getLogger(u'PptviewController') + log.info(u'loaded') def __init__(self, plugin): """ Initialise the class """ log.debug(u'Initialising') - PresentationController.__init__(self, plugin, u'Powerpoint Viewer') self.process = None + PresentationController.__init__(self, plugin, u'Powerpoint Viewer') self.pptid = None self.thumbnailpath = os.path.join(plugin.config.get_data_path(), u'pptview', u'thumbnails') self.thumbprefix = u'slide' - def is_available(self): + def check_available(self): """ PPT Viewer is able to run on this machine """ - log.debug(u'is_available') + log.debug(u'check_available') if os.name != u'nt': return False try: - self.start_process() - return True + return self.check_installed() except: return False if os.name == u'nt': + def check_installed(self): + """ + Check the viewer is installed + """ + log.debug(u'Check installed') + try: + self.start_process() + return self.process.CheckInstalled() + except: + return False + def start_process(self): """ Loads the PPTVIEWLIB library """ + if self.process is not None: + return log.debug(u'start PPTView') self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') diff --git a/openlp/plugins/presentations/lib/pptviewlib/README.TXT b/openlp/plugins/presentations/lib/pptviewlib/README.TXT index 0ffcde1bf..5afcfd3f4 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/README.TXT +++ b/openlp/plugins/presentations/lib/pptviewlib/README.TXT @@ -25,6 +25,9 @@ This library has a limit of 50 PowerPoints which can be opened simultaneously. USAGE ----- +BOOL CheckInstalled(void); + Returns TRUE if PowerPointViewer is installed. FALSE if not. + int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index 8e4cc7e82..abba3088b 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -82,6 +82,14 @@ DllExport void SetDebug(BOOL onoff) DEBUG("enabled\n"); } +DllExport BOOL CheckInstalled() +{ + DEBUG("CheckInstalled\n"); + char cmdline[MAX_PATH * 2]; + + return GetPPTViewerPath(cmdline, sizeof(cmdline)); +} + // Open the PointPoint, count the slides and take a snapshot of each slide // for use in previews // previewpath is a prefix for the location to put preview images of each slide. diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h index 3e365215b..6012b0467 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h @@ -4,6 +4,7 @@ enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING}; DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); +DllExport BOOL CheckInstalled(); DllExport void ClosePPT(int id); DllExport int GetCurrentSlide(int id); DllExport int GetSlideCount(int id); diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 8edbd5f25..6f501a092 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -20,6 +20,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA import logging +from PyQt4 import QtCore + class PresentationController(object): """ Base class for presentation controllers to inherit from @@ -32,6 +34,13 @@ class PresentationController(object): ``name`` The name that appears in the options and the media manager + ``enabled`` + The controller is enabled + + ``available`` + The controller is available on this machine. Set by init via + call to check_available + ``plugin`` The presentationplugin object @@ -40,7 +49,7 @@ class PresentationController(object): ``kill()`` Called at system exit to clean up any running presentations - ``is_available()`` + ``check_available()`` Returns True if presentation application is installed/can run on this machine ``load_presentation(presentation)`` @@ -108,8 +117,14 @@ class PresentationController(object): """ self.plugin = plugin self.name = name + self.available = self.check_available() + if self.available: + self.enabled = int(plugin.config.get_config( + name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked + else: + self.enabled = False - def is_available(self): + def check_available(self): """ Presentation app is able to run on this machine """ diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index 0cbeb4b9f..8eb04d44d 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -60,24 +60,17 @@ class PresentationTab(SettingsTab): self.VerseTypeLayout.setSpacing(8) self.VerseTypeLayout.setMargin(0) self.VerseTypeLayout.setObjectName(u'VerseTypeLayout') - self.PowerpointCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox) - self.PowerpointCheckBox.setTristate(False) - if os.name != u'nt': - self.PowerpointCheckBox.setEnabled(False) - self.PowerpointCheckBox.setObjectName(u'PowerpointCheckBox') - self.VerseDisplayLayout.addWidget(self.PowerpointCheckBox, 0, 0, 1, 1) - self.PowerpointViewerCheckBox = QtGui.QCheckBox( - self.VerseDisplayGroupBox) - self.PowerpointViewerCheckBox.setTristate(False) - if os.name != u'nt': - self.PowerpointViewerCheckBox.setEnabled(False) - self.PowerpointViewerCheckBox.setObjectName(u'PowerpointViewerCheckBox') - self.VerseDisplayLayout.addWidget( - self.PowerpointViewerCheckBox, 1, 0, 1, 1) - self.ImpressCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox) - self.ImpressCheckBox.setTristate(False) - self.ImpressCheckBox.setObjectName(u'ImpressCheckBox') - self.VerseDisplayLayout.addWidget(self.ImpressCheckBox, 2, 0, 1, 1) + self.PresenterCheckboxes = {} + index = 0 + for key in self.controllers: + controller = self.controllers[key] + checkbox = QtGui.QCheckBox(self.VerseDisplayGroupBox) + checkbox.setTristate(False) + checkbox.setEnabled(controller.available) + checkbox.setObjectName(controller.name + u'CheckBox') + self.PresenterCheckboxes[controller.name] = checkbox + index = index + 1 + self.VerseDisplayLayout.addWidget(checkbox, index, 0, 1, 1) self.PresentationThemeWidget = QtGui.QWidget(self.VerseDisplayGroupBox) self.PresentationThemeWidget.setObjectName(u'PresentationThemeWidget') self.PresentationThemeLayout = QtGui.QHBoxLayout( @@ -103,26 +96,23 @@ class PresentationTab(SettingsTab): self.PresentationLayout.addWidget(self.PresentationRightWidget) def retranslateUi(self): - self.PowerpointCheckBox.setText( - translate(u'PresentationTab', 'Powerpoint available:')) - self.PowerpointViewerCheckBox.setText( - translate(u'PresentationTab', 'PowerpointViewer available:')) - self.ImpressCheckBox.setText( - translate(u'PresentationTab', 'Impress available:')) + for key in self.controllers: + controller = self.controllers[key] + checkbox = self.PresenterCheckboxes[controller.name] + checkbox.setText(translate(u'PresentationTab', + controller.name + u' available:')) def load(self): - self.PowerpointCheckBox.setChecked( - int(self.config.get_config(u'Powerpoint', 0))) - self.PowerpointViewerCheckBox.setChecked( - int(self.config.get_config(u'Powerpoint Viewer', 0))) - self.ImpressCheckBox.setChecked( - int(self.config.get_config(u'Impress', 0))) + for key in self.controllers: + controller = self.controllers[key] + if controller.available: + checkbox = self.PresenterCheckboxes[controller.name] + checkbox.setChecked( + int(self.config.get_config(controller.name, 0))) def save(self): - self.config.set_config( - u'Powerpoint', unicode(self.PowerpointCheckBox.checkState())) - self.config.set_config( - u'Powerpoint Viewer', - unicode(self.PowerpointViewerCheckBox.checkState())) - self.config.set_config( - u'Impress', unicode(self.ImpressCheckBox.checkState())) + for key in self.controllers: + controller = self.controllers[key] + checkbox = self.PresenterCheckboxes[controller.name] + self.config.set_config( + controller.name, unicode(checkbox.checkState())) diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index f44617e7d..1827bbd4a 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -22,11 +22,12 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import os import logging -from PyQt4 import QtCore +from PyQt4 import QtGui -from openlp.core.lib import Plugin, buildIcon +from openlp.core.lib import Plugin from openlp.plugins.presentations.lib import * class PresentationPlugin(Plugin): @@ -41,7 +42,9 @@ class PresentationPlugin(Plugin): Plugin.__init__(self, u'Presentations', u'1.9.0', plugin_helpers) self.weight = -8 # Create the plugin icon - self.icon = buildIcon(u':/media/media_presentation.png') + self.icon = QtGui.QIcon() + self.icon.addPixmap(QtGui.QPixmap(u':/media/media_presentation.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) def get_settings_tab(self): """ @@ -67,25 +70,25 @@ class PresentationPlugin(Plugin): If Not do not install the plugin. """ log.debug(u'check_pre_conditions') - #Lets see if Powerpoint is required (Default is Not wanted) - controller = PowerpointController(self) - if int(self.config.get_config( - controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - if controller.is_available(): - self.registerControllers(controller) - #Lets see if Impress is required (Default is Not wanted) - controller = ImpressController(self) - if int(self.config.get_config( - controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - if controller.is_available(): - self.registerControllers(controller) - #Lets see if Powerpoint Viewer is required (Default is Not wanted) - controller = PptviewController(self) - if int(self.config.get_config( - controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - if controller.is_available(): - self.registerControllers(controller) - #If we have no available controllers disable plugin + dir = os.path.join(os.path.dirname(__file__), u'lib') + for filename in os.listdir(dir): + if filename.endswith(u'controller.py') and \ + not filename == 'presentationcontroller.py': + path = os.path.join(dir, filename) + if os.path.isfile(path): + modulename = u'openlp.plugins.presentations.lib.' + \ + os.path.splitext(filename)[0] + log.debug(u'Importing controller %s', modulename) + try: + __import__(modulename, globals(), locals(), []) + except ImportError, e: + log.error(u'Failed to import %s on path %s for reason %s', modulename, path, e.args[0]) + controller_classes = PresentationController.__subclasses__() + for controller_class in controller_classes: + controller = controller_class(self) + self.registerControllers(controller) + if controller.enabled: + controller.start_process() if len(self.controllers) > 0: return True else: @@ -94,5 +97,7 @@ class PresentationPlugin(Plugin): def finalise(self): log.debug(u'Finalise') #Ask each controller to tidy up - for controller in self.controllers: - self.controllers[controller].kill() + for key in self.controllers: + controller = self.controllers[key] + if controller.enabled: + controller.kill()