diff --git a/openlp/plugins/presentations/lib/__init__.py b/openlp/plugins/presentations/lib/__init__.py index 4b6577bdb..61aa34228 100644 --- a/openlp/plugins/presentations/lib/__init__.py +++ b/openlp/plugins/presentations/lib/__init__.py @@ -22,13 +22,10 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -import os - from presentationcontroller import PresentationController from impresscontroller import ImpressController -if os.name == u'nt': - #from powerpointcontroller import PowerpointController - from pptviewcontroller import PptviewController +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 af78f9060..869fd5fb2 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -36,7 +36,10 @@ else: from PyQt4 import QtCore -class ImpressController(object): +from presentationcontroller import PresentationController + + +class ImpressController(PresentationController): """ Class to control interactions with Impress presentations. It creates the runtime environment, loads and closes the presentation as @@ -45,14 +48,29 @@ class ImpressController(object): global log log = logging.getLogger(u'ImpressController') - def __init__(self): + def __init__(self, plugin): + """ + Initialise the class + """ log.debug(u'Initialising') + PresentationController.__init__(self, plugin, u'Impress') self.process = None self.document = None self.presentation = None - self.startOpenoffice() + self.controller = None - def startOpenoffice(self): + def is_available(self): + """ + PPT Viewer is able to run on this machine + """ + log.debug(u'is_available') + try: + self.start_process() + return True + except: + return False + + def start_process(self): """ Loads a running version of OpenOffice in the background. It is not displayed to the user but is available to the UNO interface @@ -71,7 +89,7 @@ class ImpressController(object): Called at system exit to clean up any running presentations """ log.debug(u'Kill') - self.closePresentation() + self.close_presentation() def load_presentation(self, presentation): """ @@ -86,10 +104,10 @@ class ImpressController(object): """ log.debug(u'LoadPresentation') if os.name == u'nt': - desktop = self.getCOMDesktop() + desktop = self.get_com_desktop() url = u'file:///' + presentation.replace(u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20') else: - desktop = self.getUNODesktop() + desktop = self.get_uno_desktop() url = uno.systemPathToFileUrl(presentation) if desktop is None: return @@ -100,19 +118,19 @@ class ImpressController(object): url, "_blank", 0, properties) self.presentation = self.document.getPresentation() self.presentation.start() - self.xSlideShowController = \ + self.controller = \ desktop.getCurrentComponent().Presentation.getController() except: log.exception(u'Failed to load presentation') - def getUNODesktop(self): + def get_uno_desktop(self): log.debug(u'getUNODesktop') ctx = None loop = 0 context = uno.getComponentContext() resolver = context.ServiceManager.createInstanceWithContext( u'com.sun.star.bridge.UnoUrlResolver', context) - while ctx == None and loop < 3: + while ctx is None and loop < 3: try: ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext') except: @@ -127,7 +145,7 @@ class ImpressController(object): log.exception(u'Failed to get UNO desktop') return None - def getCOMDesktop(self): + def get_com_desktop(self): log.debug(u'getCOMDesktop') try: smgr = Dispatch("com.sun.star.ServiceManager") @@ -150,43 +168,45 @@ class ImpressController(object): self.document.dispose() self.document = None - def isActive(self): + def is_loaded(self): + return self.presentation is not None and self.document is not None + + def is_active(self): + if not self.is_loaded(): + return False return self.presentation.isRunning() and self.presentation.isActive() - def resume(self): + def unblank_screen(self): return self.presentation.resume() - def pause(self): - return self.presentation.pause() - - def blankScreen(self): + def blank_screen(self): self.presentation.blankScreen(0) - def stop(self): + def stop_presentation(self): self.presentation.deactivate() # self.presdoc.end() - def go(self): + def start_presentation(self): self.presentation.activate() # self.presdoc.start() - def getSlideNumber(self): + def get_slide_number(self): return self.presentation.getCurrentSlideIndex - def setSlideNumber(self, slideno): + def goto_slide(self, slideno): self.presentation.gotoSlideIndex(slideno) - slideNumber = property(getSlideNumber, setSlideNumber) - def next_step(self): """ Triggers the next effect of slide on the running presentation """ - self.xSlideShowController.gotoNextEffect() + self.controller.gotoNextEffect() def previous_step(self): """ Triggers the previous slide on the running presentation """ - self.xSlideShowController.gotoPreviousSlide() + self.controller.gotoPreviousSlide() + + # def get_slide_preview_file(self, slide_no): diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index b239e350c..fd03f7d13 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -21,148 +21,161 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -try: + +import os +import logging + +if os.name == u'nt': from win32com.client import Dispatch -except: - pass + +from presentationcontroller import PresentationController # PPT API documentation: # http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx -class PowerPointApp(object): - def __init__(self): +class PowerpointController(PresentationController): + """ + Class to control interactions with PowerPoint Presentations + It creates the runtime Environment , Loads the and Closes the Presentation + As well as triggering the correct activities based on the users input + """ + global log + log = logging.getLogger(u'PowerpointController') + + def __init__(self, plugin): + """ + Initialise the class + """ log.debug(u'Initialising') + PresentationController.__init__(self, plugin, u'Powerpoint') self.process = None - self.document = None self.presentation = None - self.startPowerpoint() - def startPowerpoint(self): + def is_available(self): + """ + PowerPoint is able to run on this machine + """ + log.debug(u'is_available') + if os.name != u'nt': + return False try: - self._app = Dispatch(u'PowerPoint.Application') + self.start_process() + return True except: - self._app = None - return - self._app.Visible = True - self._app.WindowState = 2 - - def getApp(self): - if self._app == None: - self.createApp() - if self._app == None: - return None - if self._app.Windows.Count == 0: - self.createApp() - return self._app - - app = property(getApp) - - def quit(self): - self._app.Quit() - self._app = None - -class PowerPointPres(object): - - def __init__(self, pptApp, filename): - self.pptApp = pptApp - self.filename = filename - self.open() - - def getPres(self): - if self._pres == None: - for p in self.pptApp.app.Presentations: - if p.FullName == self.filename: - self._pres = p - break - if self._pres != None: - try: - x = self._pres.Name - except: - self._pres = None - if self._pres == None: - self.openPres() - return self._pres - - pres = property(getPres) - - def open(self): - self.pptApp.app.Presentations.Open(self.filename, False, False, True) - self._pres = self.pptApp.app.Presentations(ppt.app.Presentations.Count) - - def close(self): - self.pres.Close() - self._pres = None - - def isActive(self): - if self.pres.SlideShowWindow == None: return False - if self.pres.SlideShowWindow.View == None: - return False - return True - def resume(self): - self.pres.SlideShowSettings.Run() - self.pres.SlideShowWindow.View.State = 1 - self.pres.SlideShowWindow.Activate() + if os.name == u'nt': + def start_process(self): + """ + Loads PowerPoint process + """ + self.process = Dispatch(u'PowerPoint.Application') + self.process.Visible = True + self.process.WindowState = 2 - def pause(self): - if self.isActive(): - self.pres.SlideShowWindow.View.State = 2 + def is_loaded(self): + """ + Returns true if a presentation is loaded + """ + if self.process is None: + return False + if self.process.Windows.Count == 0: + return False + + def kill(self): + self.process.Quit() + self.process = None - def blankScreen(self): - if self.isActive(): - self.pres.SlideShowWindow.View.State = 3 + def load_presentation(self, presentation): + """ + Called when a presentation is added to the SlideController. + It builds the environment, starts communcations with the background + OpenOffice task started earlier. If OpenOffice is not present is is + started. Once the environment is available the presentation is loaded + and started. - def stop(self): - if self.isActive(): - self.pres.SlideShowWindow.View.Exit() + ``presentation`` + The file name of the presentations to run. + """ + self.filename = presentation + self.process.Presentations.Open(presentation, False, False, True) + self.presentation = self.process.Presentations(self.process.Presentations.Count) + self.start_presentation() + + def close_presentation(self): + """ + Close presentation and clean up objects + Triggerent by new object being added to SlideController orOpenLP + being shut down + """ + self.presentation.Close() + self.presentation = None - def go(self): - self.pres.SlideShowSettings.Run() + def is_active(self): + """ + Returns true if a presentation is currently active + """ + if not self.is_loaded(): + return False + if self.presentation.SlideShowWindow == None: + return False + if self.presentation.SlideShowWindow.View == None: + return False + return True - def getCurrentSlideIndex(self): - if self.isActive(): - return self.pres.SlideShowWindow.View.CurrentShowPosition - else: - return -1 + def unblank_screen(self): + """ + Unblanks (restores) the presentationn + """ + self.presentation.SlideShowSettings.Run() + self.presentation.SlideShowWindow.View.State = 1 + self.presentation.SlideShowWindow.Activate() - def setCurrentSlideIndex(self, slideno): - if not self.isActive(): - self.resume() - self.pres.SlideShowWindow.View.GotoSlide(slideno) + def blank_screen(self): + """ + Blanks the screen + """ + self.presentation.SlideShowWindow.View.State = 3 - #currentSlideIndex = property(getSlideNumber, setSlideNumber) + def stop_presentation(self): + """ + Stops the current presentation and hides the output + """ + self.presentation.SlideShowWindow.View.Exit() - def nextStep(self): - if not self.isActive(): - self.resume() - self.pres.SlideShowWindow.View.Next() + def start_presentation(self): + """ + Starts a presentation from the beginning + """ + self.presentation.SlideShowSettings.Run() + rendermanager = self.plugin.render_manager + rect = rendermanager.screen_list[rendermanager.current_display][u'size'] + self.presentation.SlideShowWindow.Top = rect.y() / 20 + self.presentation.SlideShowWindow.Height = rect.height() / 20 + self.presentation.SlideShowWindow.Left = rect.x() / 20 + self.presentation.SlideShowWindow.Width = rect.width() / 20 - def prevStep(self): - if not self.isActive(): - self.resume() - self.pres.SlideShowWindow.View.Previous() + def get_slide_number(self): + """ + Returns the current slide number + """ + return self.presentation.SlideShowWindow.View.CurrentShowPosition - def moveWindow(self, top, height, left, width): - if not self.isActive(): - self.resume() - self.pres.SlideShowWindow.Top = top / 20 - self.pres.SlideShowWindow.Height = height / 20 - self.pres.SlideShowWindow.Left = left / 20 - self.pres.SlideShowWindow.Width = width / 20 + def get_slide_count(self): + """ + Returns total number of slides + """ + return self.presentation.Slides.Count + + def goto_slide(self, slideno): + self.presentation.SlideShowWindow.View.GotoSlide(slideno) -class PowerPointSlide(object): - def __init__(self, pres, index): - self.pres = pres - self.slide = pres.Slides[index] + def next_step(self): + self.presentation.SlideShowWindow.View.Next() + + def previous_step(self): + self.presentation.SlideShowWindow.View.Previous() + + #def get_slide_preview_file(self, slide_no): - def preview(self): - if self.preview == None: - self.slide.Copy - # import win32clipboard as w - # import win32con - # w.OpenClipboard() - # self.preview = w.GetClipboardData.GetData(win32con.CF_BITMAP) - # w.CloseClipboard() - return self.preview diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 509b52ead..97c0ceb5d 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -25,8 +25,9 @@ import os import logging -from ctypes import * -from ctypes.wintypes import RECT +if os.name == u'nt': + from ctypes import * + from ctypes.wintypes import RECT from presentationcontroller import PresentationController @@ -34,7 +35,7 @@ class PptviewController(PresentationController): """ Class to control interactions with PowerPOint Viewer Presentations It creates the runtime Environment , Loads the and Closes the Presentation - As well as trigggering the correct activities based on the users input + As well as triggering the correct activities based on the users input """ global log log = logging.getLogger(u'PptviewController') @@ -43,167 +44,148 @@ class PptviewController(PresentationController): """ Initialise the class """ - log.debug(u'Initialised') + log.debug(u'Initialising') PresentationController.__init__(self, plugin, u'Powerpoint Viewer') self.process = None self.pptid = None self.thumbnailpath = os.path.join(plugin.config.get_data_path(), u'pptview', u'thumbnails') self.thumbprefix = u'slide' - self.start_process() - def start_process(self): + def is_available(self): """ - Loads the PPTVIEWLIB library + PPT Viewer is able to run on this machine """ - log.debug(u'start PPTView') - self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') - - def kill(self): - """ - Called at system exit to clean up any running presentations - """ - log.debug(u'Kill') - self.close_presentation() - - def load_presentation(self, presentation): - """ - Called when a presentation is added to the SlideController. - It builds the environment, starts communcations with the background - OpenOffice task started earlier. If OpenOffice is not present is is - started. Once the environment is available the presentation is loaded - and started. - - ``presentation`` - The file name of the presentations to run. - """ - log.debug(u'LoadPresentation') - if self.pptid >= 0: - self.close_presentation() - rendermanager = self.plugin.render_manager - #screen = rendermanager.screen_list[rendermanager.current_display] - # x? y? - rect = RECT(0, 0, rendermanager.width, rendermanager.height) - filename = str(presentation.replace(u'/', u'\\')); + log.debug(u'is_available') + if os.name != u'nt': + return False try: - self.pptid = self.process.OpenPPT(filename, None, rect, - str(self.thumbnailpath)) + self.start_process() + return True except: - log.exception(u'Failed to load presentation') + return False + if os.name == u'nt': + def start_process(self): + """ + Loads the PPTVIEWLIB library + """ + log.debug(u'start PPTView') + self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') - def close_presentation(self): - """ - Close presentation and clean up objects - Triggerent by new object being added to SlideController orOpenLP - being shut down - """ - if self.pptid < 0: - return - self.process.ClosePPT(self.pptid) - self.pptid = -1 + def kill(self): + """ + Called at system exit to clean up any running presentations + """ + log.debug(u'Kill') + self.close_presentation() - def is_active(self): - """ - Returns true if a presentation is currently active - """ - return self.pptid >= 0 + def load_presentation(self, presentation): + """ + Called when a presentation is added to the SlideController. + It builds the environment, starts communcations with the background + OpenOffice task started earlier. If OpenOffice is not present is is + started. Once the environment is available the presentation is loaded + and started. - def resume_presentation(self): - """ - Resumes a previously paused presentation - """ - if self.pptid < 0: - return - self.process.Resume(self.pptid) + ``presentation`` + The file name of the presentations to run. + """ + log.debug(u'LoadPresentation') + if self.pptid >= 0: + self.close_presentation() + rendermanager = self.plugin.render_manager + rect = rendermanager.screen_list[rendermanager.current_display][u'size'] + rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom()) + filename = str(presentation.replace(u'/', u'\\')); + try: + self.pptid = self.process.OpenPPT(filename, None, rect, + str(self.thumbnailpath)) + except: + log.exception(u'Failed to load presentation') - def pause_presentation(self): - """ - Not implemented (pauses a presentation) - """ - return + def close_presentation(self): + """ + Close presentation and clean up objects + Triggerent by new object being added to SlideController orOpenLP + being shut down + """ + self.process.ClosePPT(self.pptid) + self.pptid = -1 - def blank_screen(self): - """ - Blanks the screen - """ - if self.pptid < 0: - return - self.process.Blank(self.pptid) + def is_loaded(self): + """ + Returns true if a presentation is loaded + """ + return self.pptid >= 0 + + def is_active(self): + """ + Returns true if a presentation is currently active + """ + return self.pptid >= 0 - def unblank_screen(self): - """ - Unblanks (restores) the presentationn - """ - if self.pptid < 0: - return - self.process.Unblank(self.pptid) + def blank_screen(self): + """ + Blanks the screen + """ + self.process.Blank(self.pptid) - def stop_presentation(self): - """ - Stops the current presentation and hides the output - """ - if self.pptid < 0: - return - self.process.Stop(self.pptid) + def unblank_screen(self): + """ + Unblanks (restores) the presentationn + """ + self.process.Unblank(self.pptid) - def start_presentation(self): - """ - Starts a presentation from the beginning - """ - if self.pptid < 0: - return - self.process.RestartShow(self.pptid) + def stop_presentation(self): + """ + Stops the current presentation and hides the output + """ + self.process.Stop(self.pptid) - def get_slide_number(self): - """ - Returns the current slide number - """ - if self.pptid < 0: - return 0 - return self.process.GetCurrentSlide(self.pptid) + def start_presentation(self): + """ + Starts a presentation from the beginning + """ + self.process.RestartShow(self.pptid) - def get_slide_count(self): - """ - Returns total number of slides - """ - if self.pptid < 0: - return 0 - return self.process.GetSlideCount(self.pptid) + def get_slide_number(self): + """ + Returns the current slide number + """ + return self.process.GetCurrentSlide(self.pptid) - def goto_slide(self, slideno): - """ - Moves to a specific slide in the presentation - """ - if self.pptid < 0: - return - self.process.GotoSlide(self.pptid, slideno) + def get_slide_count(self): + """ + Returns total number of slides + """ + return self.process.GetSlideCount(self.pptid) - def next_step(self): - """ - Triggers the next effect of slide on the running presentation - """ - if self.pptid < 0: - return - self.process.NextStep(self.pptid) + def goto_slide(self, slideno): + """ + Moves to a specific slide in the presentation + """ + self.process.GotoSlide(self.pptid, slideno) - def previous_step(self): - """ - Triggers the previous slide on the running presentation - """ - if self.pptid < 0: - return - self.process.PrevStep(self.pptid) + def next_step(self): + """ + Triggers the next effect of slide on the running presentation + """ + self.process.NextStep(self.pptid) - def get_slide_preview_file(self, slide_no): - """ - Returns an image path containing a preview for the requested slide + def previous_step(self): + """ + Triggers the previous slide on the running presentation + """ + self.process.PrevStep(self.pptid) - ``slide_no`` - The slide an image is required for, starting at 1 - """ - if self.pptid < 0: - return - return os.path.join(self.thumbnailpath, - self.thumbprefix + slide_no + u'.bmp') + def get_slide_preview_file(self, slide_no): + """ + Returns an image path containing a preview for the requested slide + + ``slide_no`` + The slide an image is required for, starting at 1 + """ + return os.path.join(self.thumbnailpath, + self.thumbprefix + slide_no + u'.bmp') diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index f6a9c397f..0cbeb4b9f 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -31,7 +31,8 @@ class PresentationTab(SettingsTab): """ PresentationsTab is the Presentations settings tab in the settings dialog. """ - def __init__(self): + def __init__(self, controllers): + self.controllers = controllers SettingsTab.__init__(self, translate(u'PresentationTab', u'Presentation'), u'Presentations') diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 8dd687e88..502b71c4c 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -28,14 +28,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin -from openlp.plugins.presentations.lib import PresentationMediaItem, \ - PresentationTab, ImpressController -if os.name == u'nt': - try: - from openlp.plugins.presentations.lib import PowerpointController - except: - pass - from openlp.plugins.presentations.lib import PptviewController +from openlp.plugins.presentations.lib import * class PresentationPlugin(Plugin): @@ -57,7 +50,7 @@ class PresentationPlugin(Plugin): """ Create the settings Tab """ - self.presentation_tab = PresentationTab() + self.presentation_tab = PresentationTab(self.controllers) return self.presentation_tab def get_media_manager_item(self): @@ -77,41 +70,24 @@ class PresentationPlugin(Plugin): If Not do not install the plugin. """ log.debug('check_pre_conditions') - #Lets see if Impress is required (Default is Not wanted) + #Lets see if Powerpoint is required (Default is Not wanted) + controller = PowerpointController(self) if int(self.config.get_config( - u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - try: - if os.name == u'nt': - #Check to see if we are Win32 - from win32com.client import Dispatch - else: - #Check to see if we have uno installed - import uno - openoffice = ImpressController() - openoffice.name = u'Impress' # until controller updated - self.registerControllers(openoffice) - except: - log.exception(u'Failed to set up plugin for Impress') - if os.name == u'nt': - #Lets see if Powerpoint is required (Default is Not wanted) - if int(self.config.get_config( - u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - try: - #Check to see if we are Win32 - from win32com.client import Dispatch - powerpoint = PowerpointController() - powerpoint.name = u'Powerpoint' # until controller updated - self.registerControllers(powerpoint) - except: - log.exception(u'Failed to set up plugin for Powerpoint') - #Lets see if Powerpoint Viewer is required (Default is Not wanted) - if int(self.config.get_config( - u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: - try: - pptview = PptviewController(self) - self.registerControllers(pptview) - except: - log.exception(u'Failed to set up plugin for Powerpoint Viewer') + 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 if len(self.controllers) > 0: return True