Split live/preview presentation documents, plus fixes for Windows

bzr-revno: 720
This commit is contained in:
Jonathan Corwin 2010-03-03 08:28:39 +02:00 committed by Raoul Snyman
commit 5863541a61
8 changed files with 525 additions and 440 deletions

1
openlp/.version Normal file
View File

@ -0,0 +1 @@
1.9.0-bzr720

View File

@ -44,7 +44,7 @@ else:
from PyQt4 import QtCore
from presentationcontroller import PresentationController
from presentationcontroller import PresentationController, PresentationDocument
class ImpressController(PresentationController):
"""
@ -62,11 +62,8 @@ class ImpressController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress')
self.supports= [u'.odp', u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.supports = [u'.odp', u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.process = None
self.document = None
self.presentation = None
self.controller = None
self.desktop = None
def check_available(self):
@ -99,97 +96,6 @@ class ImpressController(PresentationController):
self.process.startDetached(cmd)
self.process.waitForStarted()
def kill(self):
"""
Called at system exit to clean up any running presentations
"""
log.debug(u'Kill OpenOffice')
self.close_presentation()
if os.name != u'nt':
desktop = self.get_uno_desktop()
try:
desktop.terminate()
except:
pass
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 presentatios to the run.
"""
log.debug(u'Load Presentation OpenOffice')
self.store_filename(presentation)
#print "s.dsk1 ", self.desktop
if os.name == u'nt':
desktop = self.get_com_desktop()
if desktop is None:
self.start_process()
desktop = self.get_com_desktop()
url = u'file:///' + presentation.replace(u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
else:
desktop = self.get_uno_desktop()
url = uno.systemPathToFileUrl(presentation)
if desktop is None:
return
self.desktop = desktop
#print "s.dsk2 ", self.desktop
properties = []
properties.append(self.create_property(u'Minimized', True))
properties = tuple(properties)
try:
self.document = desktop.loadComponentFromURL(url, u'_blank',
0, properties)
except:
log.exception(u'Failed to load presentation')
return
self.presentation = self.document.getPresentation()
self.presentation.Display = self.plugin.render_manager.screens.current_display + 1
self.controller = None
self.create_thumbnails()
def create_thumbnails(self):
"""
Create thumbnail images for presentation
"""
log.debug(u'create thumbnails OpenOffice')
if self.check_thumbnails():
return
if os.name == u'nt':
thumbdir = u'file:///' + self.thumbnailpath.replace(
u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
else:
thumbdir = uno.systemPathToFileUrl(self.thumbnailpath)
props = []
props.append(self.create_property(u'FilterName', u'impress_png_Export'))
props = tuple(props)
doc = self.document
pages = doc.getDrawPages()
for idx in range(pages.getCount()):
page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page)
path = u'%s/%s%s.png'% (thumbdir, self.thumbnailprefix,
unicode(idx + 1))
try:
doc.storeToURL(path , props)
except:
log.exception(u'%s\nUnable to store preview' % path)
def create_property(self, name, value):
log.debug(u'create property OpenOffice')
if os.name == u'nt':
prop = self.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
else:
prop = PropertyValue()
prop.Name = name
prop.Value = value
return prop
def get_uno_desktop(self):
log.debug(u'get UNO Desktop Openoffice')
ctx = None
@ -230,6 +136,113 @@ class ImpressController(PresentationController):
log.exception(u'Failed to get COM service manager')
return None
def kill(self):
"""
Called at system exit to clean up any running presentations
"""
log.debug(u'Kill OpenOffice')
for doc in self.docs:
doc.close_presentation()
if os.name != u'nt':
desktop = self.get_uno_desktop()
try:
desktop.terminate()
except:
pass
def add_doc(self, name):
log.debug(u'Add Doc OpenOffice')
doc = ImpressDocument(self, name)
self.docs.append(doc)
return doc
class ImpressDocument(PresentationDocument):
def __init__(self, controller, presentation):
log.debug(u'Init Presentation OpenOffice')
self.controller = controller
self.document = None
self.presentation = None
self.control = None
self.store_filename(presentation)
def load_presentation(self):
"""
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 presentatios to the run.
"""
log.debug(u'Load Presentation OpenOffice')
#print "s.dsk1 ", self.desktop
if os.name == u'nt':
desktop = self.controller.get_com_desktop()
if desktop is None:
self.controller.start_process()
desktop = self.controller.get_com_desktop()
url = u'file:///' + self.filepath.replace(u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
else:
desktop = self.controller.get_uno_desktop()
url = uno.systemPathToFileUrl(self.filepath)
if desktop is None:
return
self.desktop = desktop
#print "s.dsk2 ", self.desktop
properties = []
properties.append(self.create_property(u'Minimized', True))
properties = tuple(properties)
try:
self.document = desktop.loadComponentFromURL(url, u'_blank',
0, properties)
except:
log.exception(u'Failed to load presentation')
return
self.presentation = self.document.getPresentation()
self.presentation.Display = self.controller.plugin.render_manager.screens.current_display + 1
self.control = None
self.create_thumbnails()
def create_thumbnails(self):
"""
Create thumbnail images for presentation
"""
log.debug(u'create thumbnails OpenOffice')
if self.check_thumbnails():
return
if os.name == u'nt':
thumbdir = u'file:///' + self.thumbnailpath.replace(
u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
else:
thumbdir = uno.systemPathToFileUrl(self.thumbnailpath)
props = []
props.append(self.create_property(u'FilterName', u'impress_png_Export'))
props = tuple(props)
doc = self.document
pages = doc.getDrawPages()
for idx in range(pages.getCount()):
page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page)
path = u'%s/%s%s.png'% (thumbdir, self.controller.thumbnailprefix,
unicode(idx + 1))
try:
doc.storeToURL(path , props)
except:
log.exception(u'%s\nUnable to store preview' % path)
def create_property(self, name, value):
log.debug(u'create property OpenOffice')
if os.name == u'nt':
prop = self.controller.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
else:
prop = PropertyValue()
prop.Name = name
prop.Value = value
return prop
def close_presentation(self):
"""
Close presentation and clean up objects
@ -247,6 +260,7 @@ class ImpressController(PresentationController):
#We tried!
pass
self.document = None
self.controller.remove_doc(self)
def is_loaded(self):
log.debug(u'is loaded OpenOffice')
@ -268,57 +282,57 @@ class ImpressController(PresentationController):
if not self.is_loaded():
#print "False "
return False
#print "self.con ", self.controller
if self.controller is None:
#print "self.con ", self.control
if self.control is None:
return False
return True
def unblank_screen(self):
log.debug(u'unblank screen OpenOffice')
return self.controller.resume()
return self.control.resume()
def blank_screen(self):
log.debug(u'blank screen OpenOffice')
self.controller.blankScreen(0)
self.control.blankScreen(0)
def stop_presentation(self):
log.debug(u'stop presentation OpenOffice')
self.controller.deactivate()
self.control.deactivate()
def start_presentation(self):
log.debug(u'start presentation OpenOffice')
if self.controller is None or not self.controller.isRunning():
if self.control is None or not self.control.isRunning():
self.presentation.start()
# start() returns before the getCurrentComponent is ready. Try for 5 seconds
i = 1
while self.desktop.getCurrentComponent() is None and i < 50:
time.sleep(0.1)
i = i + 1
self.controller = self.desktop.getCurrentComponent().Presentation.getController()
self.control = self.desktop.getCurrentComponent().Presentation.getController()
else:
self.controller.activate()
self.control.activate()
self.goto_slide(1)
def get_slide_number(self):
return self.controller.getCurrentSlideIndex() + 1
return self.control.getCurrentSlideIndex() + 1
def get_slide_count(self):
return self.document.getDrawPages().getCount()
def goto_slide(self, slideno):
self.controller.gotoSlideIndex(slideno-1)
self.control.gotoSlideIndex(slideno-1)
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
"""
self.controller.gotoNextEffect()
self.control.gotoNextEffect()
def previous_step(self):
"""
Triggers the previous slide on the running presentation
"""
self.controller.gotoPreviousSlide()
self.control.gotoPreviousSlide()
def get_slide_preview_file(self, slide_no):
"""
@ -328,7 +342,7 @@ class ImpressController(PresentationController):
The slide an image is required for, starting at 1
"""
path = os.path.join(self.thumbnailpath,
self.thumbnailprefix + unicode(slide_no) + u'.png')
self.controller.thumbnailprefix + unicode(slide_no) + u'.png')
if os.path.isfile(path):
return path
else:

View File

@ -135,7 +135,9 @@ class PresentationMediaItem(MediaManagerItem):
self.ConfigSection, self.getFileList())
filepath = unicode((item.data(QtCore.Qt.UserRole)).toString())
for cidx in self.controllers:
self.controllers[cidx].presentation_deleted(filepath)
doc = self.controllers[cidx].add_doc(filepath)
doc.presentation_deleted()
self.controllers[cidx].remove_doc(doc)
def generateSlideData(self, service_item):
items = self.ListView.selectedIndexes()
@ -148,13 +150,14 @@ class PresentationMediaItem(MediaManagerItem):
bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
(path, name) = os.path.split(filename)
controller.store_filename(filename)
if controller.get_slide_preview_file(1) is None:
controller.load_presentation(filename)
doc = controller.add_doc(filename)
if doc.get_slide_preview_file(1) is None:
doc.load_presentation()
i = 1
img = controller.get_slide_preview_file(i)
img = doc.get_slide_preview_file(i)
while img:
service_item.add_from_command(path, name, img)
i = i + 1
img = controller.get_slide_preview_file(i)
img = doc.get_slide_preview_file(i)
controller.remove_doc(doc)
return True

View File

@ -41,37 +41,39 @@ class Controller(object):
def __init__(self, live):
self.isLive = live
self.doc = None
log.info(u'%s controller loaded' % live)
def addHandler(self, controller, file):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
self.controller = controller
if self.controller.is_loaded():
if self.doc is not None:
self.shutdown()
self.controller.load_presentation(file)
self.doc = self.controller.add_doc(file)
self.doc.load_presentation()
if self.isLive:
self.controller.start_presentation()
self.doc.start_presentation()
Receiver.send_message(u'live_slide_hide')
self.controller.slidenumber = 0
self.doc.slidenumber = 0
def activate(self):
log.debug(u'Live = %s, activate' % self.isLive)
if self.controller.is_active():
if self.doc.is_active():
return
if not self.controller.is_loaded():
self.controller.load_presentation(self.controller.filepath)
if not self.doc.is_loaded():
self.doc.load_presentation()
if self.isLive:
self.controller.start_presentation()
if self.controller.slidenumber > 1:
self.controller.goto_slide(self.controller.slidenumber)
self.doc.start_presentation()
if self.doc.slidenumber > 1:
self.doc.goto_slide(self.doc.slidenumber)
def slide(self, slide, live):
log.debug(u'Live = %s, slide' % live)
if not live:
return
self.activate()
self.controller.goto_slide(int(slide) + 1)
self.controller.poll_slidenumber(live)
self.doc.goto_slide(int(slide) + 1)
self.doc.poll_slidenumber(live)
def first(self):
"""
@ -81,8 +83,8 @@ class Controller(object):
if not self.isLive:
return
self.activate()
self.controller.start_presentation()
self.controller.poll_slidenumber(self.isLive)
self.doc.start_presentation()
self.doc.poll_slidenumber(self.isLive)
def last(self):
"""
@ -92,8 +94,8 @@ class Controller(object):
if not self.isLive:
return
self.activate()
self.controller.goto_slide(self.controller.get_slide_count())
self.controller.poll_slidenumber(self.isLive)
self.doc.goto_slide(self.doc.get_slide_count())
self.doc.poll_slidenumber(self.isLive)
def next(self):
"""
@ -103,8 +105,8 @@ class Controller(object):
if not self.isLive:
return
self.activate()
self.controller.next_step()
self.controller.poll_slidenumber(self.isLive)
self.doc.next_step()
self.doc.poll_slidenumber(self.isLive)
def previous(self):
"""
@ -114,35 +116,36 @@ class Controller(object):
if not self.isLive:
return
self.activate()
self.controller.previous_step()
self.controller.poll_slidenumber(self.isLive)
self.doc.previous_step()
self.doc.poll_slidenumber(self.isLive)
def shutdown(self):
"""
Based on the handler passed at startup triggers slide show to shut down
"""
log.debug(u'Live = %s, shutdown' % self.isLive)
self.controller.close_presentation()
self.controller.slidenumber = 0
self.doc.close_presentation()
self.doc = None
#self.doc.slidenumber = 0
#self.timer.stop()
def blank(self):
if not self.isLive:
return
if not self.controller.is_loaded():
if not self.doc.is_loaded():
return
if not self.controller.is_active():
if not self.doc.is_active():
return
self.controller.blank_screen()
self.doc.blank_screen()
def unblank(self):
if not self.isLive:
return
self.activate()
self.controller.unblank_screen()
self.doc.unblank_screen()
def poll(self):
self.controller.poll_slidenumber(self.isLive)
self.doc.poll_slidenumber(self.isLive)
class MessageListener(object):
"""

View File

@ -31,7 +31,7 @@ if os.name == u'nt':
import _winreg
import win32ui
from presentationcontroller import PresentationController
from presentationcontroller import PresentationController, PresentationDocument
# PPT API documentation:
# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
@ -52,9 +52,8 @@ class PowerpointController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint')
self.supports= [u'.ppt', u'.pps']
self.supports = [u'.ppt', u'.pps']
self.process = None
self.presentation = None
def check_available(self):
"""
@ -97,6 +96,8 @@ class PowerpointController(PresentationController):
"""
Called at system exit to clean up any running presentations
"""
for doc in self.docs:
doc.close_presentation()
if self.process is None:
return
try:
@ -105,94 +106,110 @@ class PowerpointController(PresentationController):
pass
self.process = None
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 add_doc(self, name):
log.debug(u'Add Doc PowerPoint')
doc = PowerpointDocument(self, name)
self.docs.append(doc)
return doc
``presentation``
The file name of the presentations to run.
"""
log.debug(u'LoadPresentation')
self.store_filename(presentation)
try:
if not self.process.Visible:
self.start_process()
except:
self.start_process()
try:
self.process.Presentations.Open(presentation, False, False, True)
except:
return
self.presentation = self.process.Presentations(self.process.Presentations.Count)
self.create_thumbnails()
class PowerpointDocument(PresentationDocument):
def create_thumbnails(self):
"""
Create the thumbnail images for the current presentation.
Note an alternative and quicker method would be do
self.presentation.Slides[n].Copy()
thumbnail = QApplication.clipboard.image()
But for now we want a physical file since it makes
life easier elsewhere
"""
if self.check_thumbnails():
return
self.presentation.Export(os.path.join(self.thumbnailpath, '')
, 'png', 600, 480)
def __init__(self, controller, presentation):
log.debug(u'Init Presentation Powerpoint')
self.presentation = None
self.controller = controller
self.store_filename(presentation)
def close_presentation(self):
"""
Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP
being shut down
"""
if self.presentation == None:
return
try:
self.presentation.Close()
except:
pass
self.presentation = None
def load_presentation(self):
"""
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 is_active(self):
"""
Returns true if a presentation is currently active
"""
if not self.is_loaded():
``presentation``
The file name of the presentations to run.
"""
log.debug(u'LoadPresentation')
#try:
if not self.controller.process.Visible:
self.controller.start_process()
#except:
# self.controller.start_process()
#try:
self.controller.process.Presentations.Open(self.filepath, False, False, True)
#except:
# return
self.presentation = self.controller.process.Presentations(
self.controller.process.Presentations.Count)
self.create_thumbnails()
def create_thumbnails(self):
"""
Create the thumbnail images for the current presentation.
Note an alternative and quicker method would be do
self.presentation.Slides[n].Copy()
thumbnail = QApplication.clipboard.image()
But for now we want a physical file since it makes
life easier elsewhere
"""
if self.check_thumbnails():
return
self.presentation.Export(os.path.join(self.thumbnailpath, '')
, 'png', 600, 480)
def close_presentation(self):
"""
Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP
being shut down
"""
if self.presentation == None:
return
try:
self.presentation.Close()
except:
pass
self.presentation = None
self.controller.remove_doc(self)
def is_active(self):
"""
Returns true if a presentation is currently active
"""
if not self.controller.is_loaded():
return False
try:
if self.presentation.SlideShowWindow == None:
return False
try:
if self.presentation.SlideShowWindow == None:
return False
if self.presentation.SlideShowWindow.View == None:
return False
except:
if self.presentation.SlideShowWindow.View == None:
return False
return True
except:
return False
return True
def unblank_screen(self):
"""
Unblanks (restores) the presentationn
"""
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.State = 1
self.presentation.SlideShowWindow.Activate()
def unblank_screen(self):
"""
Unblanks (restores) the presentationn
"""
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.State = 1
self.presentation.SlideShowWindow.Activate()
def blank_screen(self):
"""
Blanks the screen
"""
self.presentation.SlideShowWindow.View.State = 3
def blank_screen(self):
"""
Blanks the screen
"""
self.presentation.SlideShowWindow.View.State = 3
def stop_presentation(self):
"""
Stops the current presentation and hides the output
"""
self.presentation.SlideShowWindow.View.Exit()
def stop_presentation(self):
"""
Stops the current presentation and hides the output
"""
self.presentation.SlideShowWindow.View.Exit()
if os.name == u'nt':
def start_presentation(self):
"""
Starts a presentation from the beginning
@ -207,53 +224,53 @@ class PowerpointController(PresentationController):
dpi = 96
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.GotoSlide(1)
rendermanager = self.plugin.render_manager
rendermanager = self.controller.plugin.render_manager
rect = rendermanager.screens.current[u'size']
self.presentation.SlideShowWindow.Top = rect.y() * 72 / dpi
self.presentation.SlideShowWindow.Height = rect.height() * 72 / dpi
self.presentation.SlideShowWindow.Left = rect.x() * 72 / dpi
self.presentation.SlideShowWindow.Width = rect.width() * 72 / dpi
def get_slide_number(self):
"""
Returns the current slide number
"""
return self.presentation.SlideShowWindow.View.CurrentShowPosition
def get_slide_number(self):
"""
Returns the current slide number
"""
return self.presentation.SlideShowWindow.View.CurrentShowPosition
def get_slide_count(self):
"""
Returns total number of slides
"""
return self.presentation.Slides.Count
def get_slide_count(self):
"""
Returns total number of slides
"""
return self.presentation.Slides.Count
def goto_slide(self, slideno):
"""
Moves to a specific slide in the presentation
"""
self.presentation.SlideShowWindow.View.GotoSlide(slideno)
def goto_slide(self, slideno):
"""
Moves to a specific slide in the presentation
"""
self.presentation.SlideShowWindow.View.GotoSlide(slideno)
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
"""
self.presentation.SlideShowWindow.View.Next()
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
"""
self.presentation.SlideShowWindow.View.Next()
def previous_step(self):
"""
Triggers the previous slide on the running presentation
"""
self.presentation.SlideShowWindow.View.Previous()
def previous_step(self):
"""
Triggers the previous slide on the running presentation
"""
self.presentation.SlideShowWindow.View.Previous()
def get_slide_preview_file(self, slide_no):
"""
Returns an image path containing a preview for the requested slide
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
"""
path = os.path.join(self.thumbnailpath,
self.thumbnailprefix + unicode(slide_no) + u'.png')
if os.path.isfile(path):
return path
else:
return None
``slide_no``
The slide an image is required for, starting at 1
"""
path = os.path.join(self.thumbnailpath,
self.controller.thumbnailprefix + unicode(slide_no) + u'.png')
if os.path.isfile(path):
return path
else:
return None

View File

@ -30,7 +30,7 @@ if os.name == u'nt':
from ctypes import *
from ctypes.wintypes import RECT
from presentationcontroller import PresentationController
from presentationcontroller import PresentationController, PresentationDocument
class PptviewController(PresentationController):
"""
@ -49,8 +49,7 @@ class PptviewController(PresentationController):
log.debug(u'Initialising')
self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
self.supports= [u'.ppt', u'.pps']
self.pptid = None
self.supports = [u'.ppt', u'.pps']
def check_available(self):
"""
@ -90,123 +89,137 @@ class PptviewController(PresentationController):
Called at system exit to clean up any running presentations
"""
log.debug(u'Kill')
self.close_presentation()
for doc in self.docs:
doc.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.
def add_doc(self, name):
log.debug(u'Add Doc PPTView')
doc = PptviewDocument(self, name)
self.docs.append(doc)
return doc
``presentation``
The file name of the presentations to run.
"""
log.debug(u'LoadPresentation')
self.store_filename(presentation)
if self.pptid >= 0:
self.close_presentation()
rendermanager = self.plugin.render_manager
rect = rendermanager.screens.current[u'size']
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
filepath = str(presentation.replace(u'/', u'\\'));
try:
self.pptid = self.process.OpenPPT(filepath, None, rect,
str(os.path.join(self.thumbnailpath, self.thumbnailprefix)))
self.stop_presentation()
except:
log.exception(u'Failed to load presentation')
class PptviewDocument(PresentationDocument):
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 __init__(self, controller, presentation):
log.debug(u'Init Presentation PowerPoint')
self.presentation = None
self.pptid = None
self.controller = controller
self.store_filename(presentation)
def is_loaded(self):
"""
Returns true if a presentation is loaded
"""
if self.pptid < 0:
return False
if self.get_slide_count() < 0:
return False
return True
def load_presentation(self):
"""
Called when a presentation is added to the SlideController.
It builds the environment, starts communcations with the background
PptView task started earlier.
def is_active(self):
"""
Returns true if a presentation is currently active
"""
return self.is_loaded()
``presentation``
The file name of the presentations to run.
"""
log.debug(u'LoadPresentation')
#if self.pptid >= 0:
# self.close_presentation()
rendermanager = self.controller.plugin.render_manager
rect = rendermanager.screens.current[u'size']
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
filepath = str(self.filepath.replace(u'/', u'\\'));
try:
self.pptid = self.controller.process.OpenPPT(filepath, None, rect,
str(os.path.join(self.thumbnailpath, self.controller.thumbnailprefix)))
self.stop_presentation()
except:
log.exception(u'Failed to load presentation')
def blank_screen(self):
"""
Blanks the screen
"""
self.process.Blank(self.pptid)
def close_presentation(self):
"""
Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP
being shut down
"""
self.controller.process.ClosePPT(self.pptid)
self.pptid = -1
self.controller.remove_doc(self)
def unblank_screen(self):
"""
Unblanks (restores) the presentationn
"""
self.process.Unblank(self.pptid)
def is_loaded(self):
"""
Returns true if a presentation is loaded
"""
if self.pptid < 0:
return False
if self.get_slide_count() < 0:
return False
return True
def stop_presentation(self):
"""
Stops the current presentation and hides the output
"""
self.process.Stop(self.pptid)
def is_active(self):
"""
Returns true if a presentation is currently active
"""
return self.is_loaded()
def start_presentation(self):
"""
Starts a presentation from the beginning
"""
self.process.RestartShow(self.pptid)
def blank_screen(self):
"""
Blanks the screen
"""
self.controller.process.Blank(self.pptid)
def get_slide_number(self):
"""
Returns the current slide number
"""
return self.process.GetCurrentSlide(self.pptid)
def unblank_screen(self):
"""
Unblanks (restores) the presentationn
"""
self.controller.process.Unblank(self.pptid)
def get_slide_count(self):
"""
Returns total number of slides
"""
return self.process.GetSlideCount(self.pptid)
def stop_presentation(self):
"""
Stops the current presentation and hides the output
"""
self.controller.process.Stop(self.pptid)
def goto_slide(self, slideno):
"""
Moves to a specific slide in the presentation
"""
self.process.GotoSlide(self.pptid, slideno)
def start_presentation(self):
"""
Starts a presentation from the beginning
"""
self.controller.process.RestartShow(self.pptid)
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
"""
self.process.NextStep(self.pptid)
def get_slide_number(self):
"""
Returns the current slide number
"""
return self.controller.process.GetCurrentSlide(self.pptid)
def previous_step(self):
"""
Triggers the previous slide on the running presentation
"""
self.process.PrevStep(self.pptid)
def get_slide_count(self):
"""
Returns total number of slides
"""
return self.controller.process.GetSlideCount(self.pptid)
def get_slide_preview_file(self, slide_no):
"""
Returns an image path containing a preview for the requested slide
def goto_slide(self, slideno):
"""
Moves to a specific slide in the presentation
"""
self.controller.process.GotoSlide(self.pptid, slideno)
``slide_no``
The slide an image is required for, starting at 1
"""
path = os.path.join(self.thumbnailpath,
self.thumbnailprefix + unicode(slide_no) + u'.bmp')
if os.path.isfile(path):
return path
else:
return None
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
"""
self.controller.process.NextStep(self.pptid)
def previous_step(self):
"""
Triggers the previous slide on the running presentation
"""
self.controller.process.PrevStep(self.pptid)
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
"""
path = os.path.join(self.thumbnailpath,
self.controller.thumbnailprefix + unicode(slide_no) + u'.bmp')
if os.path.isfile(path):
return path
else:
return None

View File

@ -35,12 +35,10 @@ class PresentationController(object):
"""
Base class for presentation controllers to inherit from
Class to control interactions with presentations.
It creates the runtime environment, loads and closes the presentation as
well as triggering the correct activities based on the users input
It creates the runtime environment
To create a new controller, take a copy of this file and name it
so it ends in controller.py, i.e. foobarcontroller.py
Make sure it inhetits PresentationController
Make sure it inherits PresentationController
Then fill in the blanks. If possible try and make sure it loads
on all platforms, using for example os.name checks, although
__init__, check_available and presentation_deleted should always work.
@ -73,6 +71,88 @@ class PresentationController(object):
``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails
"""
global log
log = logging.getLogger(u'PresentationController')
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController'):
"""
This is the constructor for the presentationcontroller object.
This provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.docs = []
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
self.thumbnailroot = os.path.join(plugin.config.get_data_path(),
name, u'thumbnails')
self.thumbnailprefix = u'slide'
if not os.path.isdir(self.thumbnailroot):
os.makedirs(self.thumbnailroot)
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def start_process(self):
"""
Loads a running version of the presentation application in the background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def add_doc(self, name):
"""
Called when a new presentation document is opened
"""
doc = PresentationDocument(self, name)
self.docs.append(doc)
return doc
def remove_doc(self, doc):
"""
Called to remove an open document from the collection
"""
log.debug(u'remove_doc Presentation')
self.docs.remove(doc)
class PresentationDocument(object):
"""
Base class for presentation documents to inherit from.
Loads and closes the presentation as well as triggering the correct
activities based on the users input
**Hook Functions**
``load_presentation(presentation)``
Load a presentation file
@ -116,71 +196,12 @@ class PresentationController(object):
Returns a path to an image containing a preview for the requested slide
"""
global log
log = logging.getLogger(u'PresentationController')
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController'):
"""
This is the constructor for the presentationcontroller object.
This provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.plugin = plugin
self.name = name
self.available = self.check_available()
def __init__(self, controller, name):
self.slidenumber = 0
if self.available:
self.enabled = int(plugin.config.get_config(
name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked
else:
self.enabled = False
self.thumbnailroot = os.path.join(plugin.config.get_data_path(),
name, u'thumbnails')
self.thumbnailprefix = u'slide'
if not os.path.isdir(self.thumbnailroot):
os.makedirs(self.thumbnailroot)
self.controller = controller
self.store_filename(name)
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def presentation_deleted(self, presentation):
"""
Cleans up/deletes any controller specific files created for
a file, e.g. thumbnails
"""
self.store_filename(presentation)
shutil.rmtree(self.thumbnailpath)
def start_process(self):
"""
Loads a running version of the presentation application in the background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def load_presentation(self, presentation):
def load_presentation(self):
"""
Called when a presentation is added to the SlideController.
Loads the presentation and starts it
@ -191,16 +212,29 @@ class PresentationController(object):
"""
pass
def presentation_deleted(self):
"""
Cleans up/deletes any controller specific files created for
a file, e.g. thumbnails
"""
shutil.rmtree(self.thumbnailpath)
def store_filename(self, presentation):
"""
Set properties for the filename and thumbnail paths
"""
self.filepath = presentation
self.filename = os.path.split(presentation)[1]
self.thumbnailpath = os.path.join(self.thumbnailroot, self.filename)
self.filename = self.get_file_name(presentation)
self.thumbnailpath = self.get_thumbnail_path(presentation)
if not os.path.isdir(self.thumbnailpath):
os.mkdir(self.thumbnailpath)
def get_file_name(self, presentation):
return os.path.split(presentation)[1]
def get_thumbnail_path(self, presentation):
return os.path.join(self.controller.thumbnailroot, self.get_file_name(presentation))
def check_thumbnails(self):
"""
Returns true if the thumbnail images look to exist and are more
@ -218,10 +252,10 @@ class PresentationController(object):
Close presentation and clean up objects
Triggered by new object being added to SlideController
"""
pass
self.controller.delete_doc(self)
def is_active(self):
"""
"""
Returns True if a presentation is currently running
"""
return False

View File

@ -1 +1 @@
1.9.0-719
1.9.0-720