Individual presentation controllers are now completely self-contained.

(left out dll to see if breaks the merge, so powerpoint viewer won't work anymore. If this succeeds and is approved I'll then try pushing the dll separately)
This commit is contained in:
Jonathan Corwin 2009-09-30 20:26:51 +01:00
parent 268b0e98f3
commit bbef55326b
11 changed files with 138 additions and 93 deletions

View File

@ -23,9 +23,6 @@
############################################################################### ###############################################################################
from presentationcontroller import PresentationController from presentationcontroller import PresentationController
from impresscontroller import ImpressController
from powerpointcontroller import PowerpointController
from pptviewcontroller import PptviewController
from messagelistener import MessageListener from messagelistener import MessageListener
from mediaitem import PresentationMediaItem from mediaitem import PresentationMediaItem
from presentationtab import PresentationTab from presentationtab import PresentationTab

View File

@ -34,11 +34,8 @@ if os.name == u'nt':
else: else:
import uno import uno
from PyQt4 import QtCore
from presentationcontroller import PresentationController from presentationcontroller import PresentationController
class ImpressController(PresentationController): class ImpressController(PresentationController):
""" """
Class to control interactions with Impress presentations. Class to control interactions with Impress presentations.
@ -47,6 +44,7 @@ class ImpressController(PresentationController):
""" """
global log global log
log = logging.getLogger(u'ImpressController') log = logging.getLogger(u'ImpressController')
log.info(u'loaded')
def __init__(self, plugin): def __init__(self, plugin):
""" """
@ -59,16 +57,17 @@ class ImpressController(PresentationController):
self.presentation = None self.presentation = None
self.controller = 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') log.debug(u'check_available')
try: if os.name == u'nt':
self.start_process() 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 return True
except:
return False
def start_process(self): def start_process(self):
""" """
@ -148,13 +147,21 @@ class ImpressController(PresentationController):
def get_com_desktop(self): def get_com_desktop(self):
log.debug(u'getCOMDesktop') log.debug(u'getCOMDesktop')
try: try:
smgr = Dispatch("com.sun.star.ServiceManager") smgr = self.get_com_servicemanager()
desktop = smgr.createInstance( "com.sun.star.frame.Desktop") desktop = smgr.createInstance( "com.sun.star.frame.Desktop")
return desktop return desktop
except: except:
log.exception(u'Failed to get COM desktop') log.exception(u'Failed to get COM desktop')
return None 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): def close_presentation(self):
""" """
Close presentation and clean up objects Close presentation and clean up objects

View File

@ -94,7 +94,8 @@ class PresentationMediaItem(MediaManagerItem):
self.loadList(list) self.loadList(list)
for item in self.controllers: for item in self.controllers:
#load the drop down selection #load the drop down selection
self.DisplayTypeComboBox.addItem(item) if self.controllers[item].enabled:
self.DisplayTypeComboBox.addItem(item)
def loadList(self, list): def loadList(self, list):
for file in list: for file in list:

View File

@ -27,6 +27,7 @@ import logging
if os.name == u'nt': if os.name == u'nt':
from win32com.client import Dispatch from win32com.client import Dispatch
import _winreg
from presentationcontroller import PresentationController from presentationcontroller import PresentationController
@ -41,7 +42,8 @@ class PowerpointController(PresentationController):
""" """
global log global log
log = logging.getLogger(u'PowerpointController') log = logging.getLogger(u'PowerpointController')
log.info(u'loaded')
def __init__(self, plugin): def __init__(self, plugin):
""" """
Initialise the class Initialise the class
@ -51,18 +53,18 @@ class PowerpointController(PresentationController):
self.process = None self.process = None
self.presentation = None self.presentation = None
def is_available(self): def check_available(self):
""" """
PowerPoint is able to run on this machine PowerPoint is able to run on this machine
""" """
log.debug(u'is_available') log.debug(u'check_available')
if os.name != u'nt': if os.name == u'nt':
return False try:
try: _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close()
self.start_process() return True
return True except:
except: pass
return False return False
if os.name == u'nt': if os.name == u'nt':
def start_process(self): def start_process(self):
@ -83,6 +85,9 @@ class PowerpointController(PresentationController):
return False return False
def kill(self): def kill(self):
"""
Called at system exit to clean up any running presentations
"""
self.process.Quit() self.process.Quit()
self.process = None self.process = None

View File

@ -39,37 +39,50 @@ class PptviewController(PresentationController):
""" """
global log global log
log = logging.getLogger(u'PptviewController') log = logging.getLogger(u'PptviewController')
log.info(u'loaded')
def __init__(self, plugin): def __init__(self, plugin):
""" """
Initialise the class Initialise the class
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
self.process = None self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
self.pptid = None self.pptid = None
self.thumbnailpath = os.path.join(plugin.config.get_data_path(), self.thumbnailpath = os.path.join(plugin.config.get_data_path(),
u'pptview', u'thumbnails') u'pptview', u'thumbnails')
self.thumbprefix = u'slide' self.thumbprefix = u'slide'
def is_available(self): def check_available(self):
""" """
PPT Viewer is able to run on this machine PPT Viewer is able to run on this machine
""" """
log.debug(u'is_available') log.debug(u'check_available')
if os.name != u'nt': if os.name != u'nt':
return False return False
try: try:
self.start_process() return self.check_installed()
return True
except: except:
return False return False
if os.name == u'nt': 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): def start_process(self):
""" """
Loads the PPTVIEWLIB library Loads the PPTVIEWLIB library
""" """
if self.process is not None:
return
log.debug(u'start PPTView') log.debug(u'start PPTView')
self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll') self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')

View File

@ -25,6 +25,9 @@ This library has a limit of 50 PowerPoints which can be opened simultaneously.
USAGE USAGE
----- -----
BOOL CheckInstalled(void);
Returns TRUE if PowerPointViewer is installed. FALSE if not.
int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);
Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly

View File

@ -82,6 +82,14 @@ DllExport void SetDebug(BOOL onoff)
DEBUG("enabled\n"); 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 // Open the PointPoint, count the slides and take a snapshot of each slide
// for use in previews // for use in previews
// previewpath is a prefix for the location to put preview images of each slide. // previewpath is a prefix for the location to put preview images of each slide.

View File

@ -4,6 +4,7 @@
enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING}; enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING};
DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);
DllExport BOOL CheckInstalled();
DllExport void ClosePPT(int id); DllExport void ClosePPT(int id);
DllExport int GetCurrentSlide(int id); DllExport int GetCurrentSlide(int id);
DllExport int GetSlideCount(int id); DllExport int GetSlideCount(int id);

View File

@ -20,6 +20,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
import logging import logging
from PyQt4 import QtCore
class PresentationController(object): class PresentationController(object):
""" """
Base class for presentation controllers to inherit from Base class for presentation controllers to inherit from
@ -32,6 +34,13 @@ class PresentationController(object):
``name`` ``name``
The name that appears in the options and the media manager 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`` ``plugin``
The presentationplugin object The presentationplugin object
@ -40,7 +49,7 @@ class PresentationController(object):
``kill()`` ``kill()``
Called at system exit to clean up any running presentations 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 Returns True if presentation application is installed/can run on this machine
``load_presentation(presentation)`` ``load_presentation(presentation)``
@ -108,8 +117,14 @@ class PresentationController(object):
""" """
self.plugin = plugin self.plugin = plugin
self.name = name 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 Presentation app is able to run on this machine
""" """

View File

@ -60,24 +60,17 @@ class PresentationTab(SettingsTab):
self.VerseTypeLayout.setSpacing(8) self.VerseTypeLayout.setSpacing(8)
self.VerseTypeLayout.setMargin(0) self.VerseTypeLayout.setMargin(0)
self.VerseTypeLayout.setObjectName(u'VerseTypeLayout') self.VerseTypeLayout.setObjectName(u'VerseTypeLayout')
self.PowerpointCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox) self.PresenterCheckboxes = {}
self.PowerpointCheckBox.setTristate(False) index = 0
if os.name != u'nt': for key in self.controllers:
self.PowerpointCheckBox.setEnabled(False) controller = self.controllers[key]
self.PowerpointCheckBox.setObjectName(u'PowerpointCheckBox') checkbox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
self.VerseDisplayLayout.addWidget(self.PowerpointCheckBox, 0, 0, 1, 1) checkbox.setTristate(False)
self.PowerpointViewerCheckBox = QtGui.QCheckBox( checkbox.setEnabled(controller.available)
self.VerseDisplayGroupBox) checkbox.setObjectName(controller.name + u'CheckBox')
self.PowerpointViewerCheckBox.setTristate(False) self.PresenterCheckboxes[controller.name] = checkbox
if os.name != u'nt': index = index + 1
self.PowerpointViewerCheckBox.setEnabled(False) self.VerseDisplayLayout.addWidget(checkbox, index, 0, 1, 1)
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.PresentationThemeWidget = QtGui.QWidget(self.VerseDisplayGroupBox) self.PresentationThemeWidget = QtGui.QWidget(self.VerseDisplayGroupBox)
self.PresentationThemeWidget.setObjectName(u'PresentationThemeWidget') self.PresentationThemeWidget.setObjectName(u'PresentationThemeWidget')
self.PresentationThemeLayout = QtGui.QHBoxLayout( self.PresentationThemeLayout = QtGui.QHBoxLayout(
@ -103,26 +96,23 @@ class PresentationTab(SettingsTab):
self.PresentationLayout.addWidget(self.PresentationRightWidget) self.PresentationLayout.addWidget(self.PresentationRightWidget)
def retranslateUi(self): def retranslateUi(self):
self.PowerpointCheckBox.setText( for key in self.controllers:
translate(u'PresentationTab', 'Powerpoint available:')) controller = self.controllers[key]
self.PowerpointViewerCheckBox.setText( checkbox = self.PresenterCheckboxes[controller.name]
translate(u'PresentationTab', 'PowerpointViewer available:')) checkbox.setText(translate(u'PresentationTab',
self.ImpressCheckBox.setText( controller.name + u' available:'))
translate(u'PresentationTab', 'Impress available:'))
def load(self): def load(self):
self.PowerpointCheckBox.setChecked( for key in self.controllers:
int(self.config.get_config(u'Powerpoint', 0))) controller = self.controllers[key]
self.PowerpointViewerCheckBox.setChecked( if controller.available:
int(self.config.get_config(u'Powerpoint Viewer', 0))) checkbox = self.PresenterCheckboxes[controller.name]
self.ImpressCheckBox.setChecked( checkbox.setChecked(
int(self.config.get_config(u'Impress', 0))) int(self.config.get_config(controller.name, 0)))
def save(self): def save(self):
self.config.set_config( for key in self.controllers:
u'Powerpoint', unicode(self.PowerpointCheckBox.checkState())) controller = self.controllers[key]
self.config.set_config( checkbox = self.PresenterCheckboxes[controller.name]
u'Powerpoint Viewer', self.config.set_config(
unicode(self.PowerpointViewerCheckBox.checkState())) controller.name, unicode(checkbox.checkState()))
self.config.set_config(
u'Impress', unicode(self.ImpressCheckBox.checkState()))

View File

@ -22,11 +22,12 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import os
import logging 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 * from openlp.plugins.presentations.lib import *
class PresentationPlugin(Plugin): class PresentationPlugin(Plugin):
@ -41,7 +42,9 @@ class PresentationPlugin(Plugin):
Plugin.__init__(self, u'Presentations', u'1.9.0', plugin_helpers) Plugin.__init__(self, u'Presentations', u'1.9.0', plugin_helpers)
self.weight = -8 self.weight = -8
# Create the plugin icon # 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): def get_settings_tab(self):
""" """
@ -67,25 +70,25 @@ class PresentationPlugin(Plugin):
If Not do not install the plugin. If Not do not install the plugin.
""" """
log.debug(u'check_pre_conditions') log.debug(u'check_pre_conditions')
#Lets see if Powerpoint is required (Default is Not wanted) dir = os.path.join(os.path.dirname(__file__), u'lib')
controller = PowerpointController(self) for filename in os.listdir(dir):
if int(self.config.get_config( if filename.endswith(u'controller.py') and \
controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: not filename == 'presentationcontroller.py':
if controller.is_available(): path = os.path.join(dir, filename)
self.registerControllers(controller) if os.path.isfile(path):
#Lets see if Impress is required (Default is Not wanted) modulename = u'openlp.plugins.presentations.lib.' + \
controller = ImpressController(self) os.path.splitext(filename)[0]
if int(self.config.get_config( log.debug(u'Importing controller %s', modulename)
controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: try:
if controller.is_available(): __import__(modulename, globals(), locals(), [])
self.registerControllers(controller) except ImportError, e:
#Lets see if Powerpoint Viewer is required (Default is Not wanted) log.error(u'Failed to import %s on path %s for reason %s', modulename, path, e.args[0])
controller = PptviewController(self) controller_classes = PresentationController.__subclasses__()
if int(self.config.get_config( for controller_class in controller_classes:
controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: controller = controller_class(self)
if controller.is_available(): self.registerControllers(controller)
self.registerControllers(controller) if controller.enabled:
#If we have no available controllers disable plugin controller.start_process()
if len(self.controllers) > 0: if len(self.controllers) > 0:
return True return True
else: else:
@ -94,5 +97,7 @@ class PresentationPlugin(Plugin):
def finalise(self): def finalise(self):
log.debug(u'Finalise') log.debug(u'Finalise')
#Ask each controller to tidy up #Ask each controller to tidy up
for controller in self.controllers: for key in self.controllers:
self.controllers[controller].kill() controller = self.controllers[key]
if controller.enabled:
controller.kill()