This commit is contained in:
Tim Bentley 2010-03-03 17:51:19 +00:00
commit bb0a3f7293
10 changed files with 530 additions and 441 deletions

View File

@ -34,6 +34,7 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger() log = logging.getLogger()
import openlp
from openlp.core.lib import Receiver, str_to_bool from openlp.core.lib import Receiver, str_to_bool
from openlp.core.resources import qInitResources from openlp.core.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen, ScreenList from openlp.core.ui import MainWindow, SplashScreen, ScreenList
@ -77,8 +78,8 @@ class OpenLP(QtGui.QApplication):
Run the OpenLP application. Run the OpenLP application.
""" """
#Load and store current Application Version #Load and store current Application Version
filepath = os.path.split(os.path.abspath(__file__))[0] filepath = os.path.split(os.path.abspath(openlp.__file__))[0]
filepath = os.path.abspath(os.path.join(filepath, u'version.txt')) filepath = os.path.abspath(os.path.join(filepath, u'.version'))
fversion = None fversion = None
try: try:
fversion = open(filepath, u'r') fversion = open(filepath, u'r')

1
openlp/.version Normal file
View File

@ -0,0 +1 @@
1.9.0-bzr721

View File

@ -30,6 +30,8 @@ import chardet
import codecs import codecs
import re import re
from PyQt4 import QtCore
from openlp.core.lib import Receiver from openlp.core.lib import Receiver
from db import BibleDB from db import BibleDB
@ -94,10 +96,11 @@ class OSISBible(BibleDB):
Loads a Bible from file. Loads a Bible from file.
""" """
log.debug(u'Starting OSIS import from "%s"' % self.filename) log.debug(u'Starting OSIS import from "%s"' % self.filename)
self.wizard.incrementProgressBar(u'Detecting encoding (this may take a few minutes)...')
detect_file = None detect_file = None
try: try:
detect_file = open(self.filename, u'r') detect_file = open(self.filename, u'r')
details = chardet.detect(detect_file.read(3000)) details = chardet.detect(detect_file.read())
except: except:
log.exception(u'Failed to detect OSIS file encoding') log.exception(u'Failed to detect OSIS file encoding')
return return

View File

@ -44,7 +44,7 @@ else:
from PyQt4 import QtCore from PyQt4 import QtCore
from presentationcontroller import PresentationController from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -62,11 +62,8 @@ class ImpressController(PresentationController):
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress') 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.process = None
self.document = None
self.presentation = None
self.controller = None
self.desktop = None self.desktop = None
def check_available(self): def check_available(self):
@ -99,97 +96,6 @@ class ImpressController(PresentationController):
self.process.startDetached(cmd) self.process.startDetached(cmd)
self.process.waitForStarted() 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): def get_uno_desktop(self):
log.debug(u'get UNO Desktop Openoffice') log.debug(u'get UNO Desktop Openoffice')
ctx = None ctx = None
@ -230,6 +136,113 @@ class ImpressController(PresentationController):
log.exception(u'Failed to get COM service manager') log.exception(u'Failed to get COM service manager')
return None 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): def close_presentation(self):
""" """
Close presentation and clean up objects Close presentation and clean up objects
@ -247,6 +260,7 @@ class ImpressController(PresentationController):
#We tried! #We tried!
pass pass
self.document = None self.document = None
self.controller.remove_doc(self)
def is_loaded(self): def is_loaded(self):
log.debug(u'is loaded OpenOffice') log.debug(u'is loaded OpenOffice')
@ -268,57 +282,57 @@ class ImpressController(PresentationController):
if not self.is_loaded(): if not self.is_loaded():
#print "False " #print "False "
return False return False
#print "self.con ", self.controller #print "self.con ", self.control
if self.controller is None: if self.control is None:
return False return False
return True return True
def unblank_screen(self): def unblank_screen(self):
log.debug(u'unblank screen OpenOffice') log.debug(u'unblank screen OpenOffice')
return self.controller.resume() return self.control.resume()
def blank_screen(self): def blank_screen(self):
log.debug(u'blank screen OpenOffice') log.debug(u'blank screen OpenOffice')
self.controller.blankScreen(0) self.control.blankScreen(0)
def stop_presentation(self): def stop_presentation(self):
log.debug(u'stop presentation OpenOffice') log.debug(u'stop presentation OpenOffice')
self.controller.deactivate() self.control.deactivate()
def start_presentation(self): def start_presentation(self):
log.debug(u'start presentation OpenOffice') 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() self.presentation.start()
# start() returns before the getCurrentComponent is ready. Try for 5 seconds # start() returns before the getCurrentComponent is ready. Try for 5 seconds
i = 1 i = 1
while self.desktop.getCurrentComponent() is None and i < 50: while self.desktop.getCurrentComponent() is None and i < 50:
time.sleep(0.1) time.sleep(0.1)
i = i + 1 i = i + 1
self.controller = self.desktop.getCurrentComponent().Presentation.getController() self.control = self.desktop.getCurrentComponent().Presentation.getController()
else: else:
self.controller.activate() self.control.activate()
self.goto_slide(1) self.goto_slide(1)
def get_slide_number(self): def get_slide_number(self):
return self.controller.getCurrentSlideIndex() + 1 return self.control.getCurrentSlideIndex() + 1
def get_slide_count(self): def get_slide_count(self):
return self.document.getDrawPages().getCount() return self.document.getDrawPages().getCount()
def goto_slide(self, slideno): def goto_slide(self, slideno):
self.controller.gotoSlideIndex(slideno-1) self.control.gotoSlideIndex(slideno-1)
def next_step(self): def next_step(self):
""" """
Triggers the next effect of slide on the running presentation Triggers the next effect of slide on the running presentation
""" """
self.controller.gotoNextEffect() self.control.gotoNextEffect()
def previous_step(self): def previous_step(self):
""" """
Triggers the previous slide on the running presentation Triggers the previous slide on the running presentation
""" """
self.controller.gotoPreviousSlide() self.control.gotoPreviousSlide()
def get_slide_preview_file(self, slide_no): 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 The slide an image is required for, starting at 1
""" """
path = os.path.join(self.thumbnailpath, 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): if os.path.isfile(path):
return path return path
else: else:

View File

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

View File

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

View File

@ -31,7 +31,7 @@ if os.name == u'nt':
import _winreg import _winreg
import win32ui import win32ui
from presentationcontroller import PresentationController from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -52,9 +52,8 @@ class PowerpointController(PresentationController):
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint') PresentationController.__init__(self, plugin, u'Powerpoint')
self.supports= [u'.ppt', u'.pps'] self.supports = [u'.ppt', u'.pps']
self.process = None self.process = None
self.presentation = None
def check_available(self): def check_available(self):
""" """
@ -97,6 +96,8 @@ class PowerpointController(PresentationController):
""" """
Called at system exit to clean up any running presentations Called at system exit to clean up any running presentations
""" """
for doc in self.docs:
doc.close_presentation()
if self.process is None: if self.process is None:
return return
try: try:
@ -105,94 +106,110 @@ class PowerpointController(PresentationController):
pass pass
self.process = None self.process = None
def load_presentation(self, presentation): def add_doc(self, name):
""" log.debug(u'Add Doc PowerPoint')
Called when a presentation is added to the SlideController. doc = PowerpointDocument(self, name)
It builds the environment, starts communcations with the background self.docs.append(doc)
OpenOffice task started earlier. If OpenOffice is not present is is return doc
started. Once the environment is available the presentation is loaded
and started.
``presentation`` class PowerpointDocument(PresentationDocument):
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()
def create_thumbnails(self): def __init__(self, controller, presentation):
""" log.debug(u'Init Presentation Powerpoint')
Create the thumbnail images for the current presentation. self.presentation = None
Note an alternative and quicker method would be do self.controller = controller
self.presentation.Slides[n].Copy() self.store_filename(presentation)
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): def load_presentation(self):
""" """
Close presentation and clean up objects Called when a presentation is added to the SlideController.
Triggerent by new object being added to SlideController orOpenLP It builds the environment, starts communcations with the background
being shut down OpenOffice task started earlier. If OpenOffice is not present is is
""" started. Once the environment is available the presentation is loaded
if self.presentation == None: and started.
return
try:
self.presentation.Close()
except:
pass
self.presentation = None
def is_active(self): ``presentation``
""" The file name of the presentations to run.
Returns true if a presentation is currently active """
""" log.debug(u'LoadPresentation')
if not self.is_loaded(): #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 return False
try: if self.presentation.SlideShowWindow.View == None:
if self.presentation.SlideShowWindow == None:
return False
if self.presentation.SlideShowWindow.View == None:
return False
except:
return False return False
return True except:
return False
return True
def unblank_screen(self): def unblank_screen(self):
""" """
Unblanks (restores) the presentationn Unblanks (restores) the presentationn
""" """
self.presentation.SlideShowSettings.Run() self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.State = 1 self.presentation.SlideShowWindow.View.State = 1
self.presentation.SlideShowWindow.Activate() self.presentation.SlideShowWindow.Activate()
def blank_screen(self): def blank_screen(self):
""" """
Blanks the screen Blanks the screen
""" """
self.presentation.SlideShowWindow.View.State = 3 self.presentation.SlideShowWindow.View.State = 3
def stop_presentation(self): def stop_presentation(self):
""" """
Stops the current presentation and hides the output Stops the current presentation and hides the output
""" """
self.presentation.SlideShowWindow.View.Exit() self.presentation.SlideShowWindow.View.Exit()
if os.name == u'nt':
def start_presentation(self): def start_presentation(self):
""" """
Starts a presentation from the beginning Starts a presentation from the beginning
@ -207,53 +224,53 @@ class PowerpointController(PresentationController):
dpi = 96 dpi = 96
self.presentation.SlideShowSettings.Run() self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.GotoSlide(1) self.presentation.SlideShowWindow.View.GotoSlide(1)
rendermanager = self.plugin.render_manager rendermanager = self.controller.plugin.render_manager
rect = rendermanager.screens.current[u'size'] rect = rendermanager.screens.current[u'size']
self.presentation.SlideShowWindow.Top = rect.y() * 72 / dpi self.presentation.SlideShowWindow.Top = rect.y() * 72 / dpi
self.presentation.SlideShowWindow.Height = rect.height() * 72 / dpi self.presentation.SlideShowWindow.Height = rect.height() * 72 / dpi
self.presentation.SlideShowWindow.Left = rect.x() * 72 / dpi self.presentation.SlideShowWindow.Left = rect.x() * 72 / dpi
self.presentation.SlideShowWindow.Width = rect.width() * 72 / dpi self.presentation.SlideShowWindow.Width = rect.width() * 72 / dpi
def get_slide_number(self): def get_slide_number(self):
""" """
Returns the current slide number Returns the current slide number
""" """
return self.presentation.SlideShowWindow.View.CurrentShowPosition return self.presentation.SlideShowWindow.View.CurrentShowPosition
def get_slide_count(self): def get_slide_count(self):
""" """
Returns total number of slides Returns total number of slides
""" """
return self.presentation.Slides.Count return self.presentation.Slides.Count
def goto_slide(self, slideno): def goto_slide(self, slideno):
""" """
Moves to a specific slide in the presentation Moves to a specific slide in the presentation
""" """
self.presentation.SlideShowWindow.View.GotoSlide(slideno) self.presentation.SlideShowWindow.View.GotoSlide(slideno)
def next_step(self): def next_step(self):
""" """
Triggers the next effect of slide on the running presentation Triggers the next effect of slide on the running presentation
""" """
self.presentation.SlideShowWindow.View.Next() self.presentation.SlideShowWindow.View.Next()
def previous_step(self): def previous_step(self):
""" """
Triggers the previous slide on the running presentation Triggers the previous slide on the running presentation
""" """
self.presentation.SlideShowWindow.View.Previous() self.presentation.SlideShowWindow.View.Previous()
def get_slide_preview_file(self, slide_no): def get_slide_preview_file(self, slide_no):
""" """
Returns an image path containing a preview for the requested slide Returns an image path containing a preview for the requested slide
``slide_no`` ``slide_no``
The slide an image is required for, starting at 1 The slide an image is required for, starting at 1
""" """
path = os.path.join(self.thumbnailpath, 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): if os.path.isfile(path):
return path return path
else: else:
return None return None

View File

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

@ -37,12 +37,10 @@ class PresentationController(object):
""" """
Base class for presentation controllers to inherit from Base class for presentation controllers to inherit from
Class to control interactions with presentations. Class to control interactions with presentations.
It creates the runtime environment, loads and closes the presentation as It creates the runtime environment
well as triggering the correct activities based on the users input
To create a new controller, take a copy of this file and name it To create a new controller, take a copy of this file and name it
so it ends in controller.py, i.e. foobarcontroller.py 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 Then fill in the blanks. If possible try and make sure it loads
on all platforms, using for example os.name checks, although on all platforms, using for example os.name checks, although
__init__, check_available and presentation_deleted should always work. __init__, check_available and presentation_deleted should always work.
@ -75,6 +73,86 @@ class PresentationController(object):
``presentation_deleted()`` ``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails Deletes presentation specific files, e.g. thumbnails
"""
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_presentation(presentation)``
Load a presentation file Load a presentation file
@ -118,69 +196,12 @@ class PresentationController(object):
Returns a path to an image containing a preview for the requested slide Returns a path to an image containing a preview for the requested slide
""" """
log.info(u'PresentationController loaded') def __init__(self, controller, name):
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()
self.slidenumber = 0 self.slidenumber = 0
if self.available: self.controller = controller
self.enabled = int(plugin.config.get_config( self.store_filename(name)
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): def load_presentation(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):
""" """
Called when a presentation is added to the SlideController. Called when a presentation is added to the SlideController.
Loads the presentation and starts it Loads the presentation and starts it
@ -191,16 +212,29 @@ class PresentationController(object):
""" """
pass 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): def store_filename(self, presentation):
""" """
Set properties for the filename and thumbnail paths Set properties for the filename and thumbnail paths
""" """
self.filepath = presentation self.filepath = presentation
self.filename = os.path.split(presentation)[1] self.filename = self.get_file_name(presentation)
self.thumbnailpath = os.path.join(self.thumbnailroot, self.filename) self.thumbnailpath = self.get_thumbnail_path(presentation)
if not os.path.isdir(self.thumbnailpath): if not os.path.isdir(self.thumbnailpath):
os.mkdir(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): def check_thumbnails(self):
""" """
Returns true if the thumbnail images look to exist and are more 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 Close presentation and clean up objects
Triggered by new object being added to SlideController Triggered by new object being added to SlideController
""" """
pass self.controller.delete_doc(self)
def is_active(self): def is_active(self):
""" """
Returns True if a presentation is currently running Returns True if a presentation is currently running
""" """
return False return False

View File

@ -1 +1 @@
1.9.0-719 1.9.0-721