Merge lp:~j-corwin/openlp/presentations into lp:openlp

Proposed by Jonathan Corwin
Status: Merged
Merged at revision: not available
Proposed branch: lp:~j-corwin/openlp/presentations
Merge into: lp:openlp
Diff against target: 1067 lines
8 files modified
openlp/plugins/presentations/lib/__init__.py (+3/-5)
openlp/plugins/presentations/lib/impresscontroller.py (+48/-28)
openlp/plugins/presentations/lib/messagelistener.py (+4/-4)
openlp/plugins/presentations/lib/powerpointcontroller.py (+150/-9)
openlp/plugins/presentations/lib/pptviewcontroller.py (+152/-142)
openlp/plugins/presentations/lib/presentationcontroller.py (+227/-0)
openlp/plugins/presentations/lib/presentationtab.py (+2/-1)
openlp/plugins/presentations/presentationplugin.py (+21/-43)
To merge this branch: bzr merge lp:~j-corwin/openlp/presentations
Reviewer Review Type Date Requested Status
Jon Tibble (community) Approve
Tim Bentley Approve
Review via email: mp+12472@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jonathan Corwin (j-corwin) wrote :

The three presentation controllers now inherit from common presentationcontroller.
Add PowerPoint support
PowerPointViewer now outputs to correct screen

Revision history for this message
Jonathan Corwin (j-corwin) wrote :

Note my idea for presentationcontrollers is for them to be loaded dynamically like the plugins are. I.e. for PresentationPlugin to have no hardcoded knowledge of which controllers exist, what they are called or which platforms they work on.

PresentationTab could be passed the controllers array and draw the UI automatically from these.

This way others could just drop in a new *controller.py should any new presentation types be requested (Keynote? PDF? Google docs? etc) and this would get picked up automatically.

Revision history for this message
Tim Bentley (trb143) wrote :

Very good I like it.
There is some strangeness on line 281 , 289 and a bit further down.
Looks like a class during a merge which will lead to a compile problem.

review: Needs Fixing
Revision history for this message
Jonathan Corwin (j-corwin) wrote :

Any ideas what I need to do to fix it?

281 +<<<<<<< TREE
282 self._app = None
283 return
284 self._app.Visible = True
285 @@ -165,3 +187,122 @@
286 # self.preview = w.GetClipboardData.GetData(win32con.CF_BITMAP)
287 # w.CloseClipboard()
288 return self.preview
289 +=======
<snip>
407 +>>>>>>> MERGE-SOURCE

Lines 282->284 & 286->288 have been deleted in my version.

Revision history for this message
Tim Bentley (trb143) wrote :

We can fix it up on the merge.
If Meths pops up I can do this this afternoon otherwise it will have to wait for the Raoul to reappear.

review: Approve
Revision history for this message
Jon Tibble (meths) wrote :

Looks good

review: Approve
lp:~j-corwin/openlp/presentations updated
575. By Jonathan Corwin

Jons Presentation merge with hack to fix conflicts

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/plugins/presentations/lib/__init__.py'
2--- openlp/plugins/presentations/lib/__init__.py 2009-09-25 16:23:44 +0000
3+++ openlp/plugins/presentations/lib/__init__.py 2009-09-26 21:10:22 +0000
4@@ -22,12 +22,10 @@
5 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
6 ###############################################################################
7
8-import os
9-
10+from presentationcontroller import PresentationController
11 from impresscontroller import ImpressController
12-if os.name == u'nt':
13- #from powerpointcontroller import PowerpointController
14- from pptviewcontroller import PptviewController
15+from powerpointcontroller import PowerpointController
16+from pptviewcontroller import PptviewController
17 from messagelistener import MessageListener
18 from mediaitem import PresentationMediaItem
19 from presentationtab import PresentationTab
20
21=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
22--- openlp/plugins/presentations/lib/impresscontroller.py 2009-09-25 23:06:54 +0000
23+++ openlp/plugins/presentations/lib/impresscontroller.py 2009-09-26 21:10:22 +0000
24@@ -36,7 +36,10 @@
25
26 from PyQt4 import QtCore
27
28-class ImpressController(object):
29+from presentationcontroller import PresentationController
30+
31+
32+class ImpressController(PresentationController):
33 """
34 Class to control interactions with Impress presentations.
35 It creates the runtime environment, loads and closes the presentation as
36@@ -45,14 +48,29 @@
37 global log
38 log = logging.getLogger(u'ImpressController')
39
40- def __init__(self):
41+ def __init__(self, plugin):
42+ """
43+ Initialise the class
44+ """
45 log.debug(u'Initialising')
46+ PresentationController.__init__(self, plugin, u'Impress')
47 self.process = None
48 self.document = None
49 self.presentation = None
50- self.startOpenoffice()
51+ self.controller = None
52
53- def startOpenoffice(self):
54+ def is_available(self):
55+ """
56+ PPT Viewer is able to run on this machine
57+ """
58+ log.debug(u'is_available')
59+ try:
60+ self.start_process()
61+ return True
62+ except:
63+ return False
64+
65+ def start_process(self):
66 """
67 Loads a running version of OpenOffice in the background.
68 It is not displayed to the user but is available to the UNO interface
69@@ -71,9 +89,9 @@
70 Called at system exit to clean up any running presentations
71 """
72 log.debug(u'Kill')
73- self.closePresentation()
74+ self.close_presentation()
75
76- def loadPresentation(self, presentation):
77+ def load_presentation(self, presentation):
78 """
79 Called when a presentation is added to the SlideController.
80 It builds the environment, starts communcations with the background
81@@ -86,10 +104,10 @@
82 """
83 log.debug(u'LoadPresentation')
84 if os.name == u'nt':
85- desktop = self.getCOMDesktop()
86+ desktop = self.get_com_desktop()
87 url = u'file:///' + presentation.replace(u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
88 else:
89- desktop = self.getUNODesktop()
90+ desktop = self.get_uno_desktop()
91 url = uno.systemPathToFileUrl(presentation)
92 if desktop is None:
93 return
94@@ -100,12 +118,12 @@
95 url, "_blank", 0, properties)
96 self.presentation = self.document.getPresentation()
97 self.presentation.start()
98- self.xSlideShowController = \
99+ self.controller = \
100 desktop.getCurrentComponent().Presentation.getController()
101 except:
102 log.exception(u'Failed to load presentation')
103
104- def getUNODesktop(self):
105+ def get_uno_desktop(self):
106 log.debug(u'getUNODesktop')
107 ctx = None
108 loop = 0
109@@ -127,7 +145,7 @@
110 log.exception(u'Failed to get UNO desktop')
111 return None
112
113- def getCOMDesktop(self):
114+ def get_com_desktop(self):
115 log.debug(u'getCOMDesktop')
116 try:
117 smgr = Dispatch("com.sun.star.ServiceManager")
118@@ -137,7 +155,7 @@
119 log.exception(u'Failed to get COM desktop')
120 return None
121
122- def closePresentation(self):
123+ def close_presentation(self):
124 """
125 Close presentation and clean up objects
126 Triggerent by new object being added to SlideController orOpenLP
127@@ -150,43 +168,45 @@
128 self.document.dispose()
129 self.document = None
130
131- def isActive(self):
132+ def is_loaded(self):
133+ return self.presentation is not None and self.document is not None
134+
135+ def is_active(self):
136+ if not self.is_loaded():
137+ return False
138 return self.presentation.isRunning() and self.presentation.isActive()
139
140- def resume(self):
141+ def unblank_screen(self):
142 return self.presentation.resume()
143
144- def pause(self):
145- return self.presentation.pause()
146-
147- def blankScreen(self):
148+ def blank_screen(self):
149 self.presentation.blankScreen(0)
150
151- def stop(self):
152+ def stop_presentation(self):
153 self.presentation.deactivate()
154 # self.presdoc.end()
155
156- def go(self):
157+ def start_presentation(self):
158 self.presentation.activate()
159 # self.presdoc.start()
160
161- def getSlideNumber(self):
162+ def get_slide_number(self):
163 return self.presentation.getCurrentSlideIndex
164
165- def setSlideNumber(self, slideno):
166+ def goto_slide(self, slideno):
167 self.presentation.gotoSlideIndex(slideno)
168
169- slideNumber = property(getSlideNumber, setSlideNumber)
170-
171- def nextStep(self):
172+ def next_step(self):
173 """
174 Triggers the next effect of slide on the running presentation
175 """
176- self.xSlideShowController.gotoNextEffect()
177+ self.controller.gotoNextEffect()
178
179- def previousStep(self):
180+ def previous_step(self):
181 """
182 Triggers the previous slide on the running presentation
183 """
184- self.xSlideShowController.gotoPreviousSlide()
185+ self.controller.gotoPreviousSlide()
186+
187+ # def get_slide_preview_file(self, slide_no):
188
189
190=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
191--- openlp/plugins/presentations/lib/messagelistener.py 2009-09-25 00:43:42 +0000
192+++ openlp/plugins/presentations/lib/messagelistener.py 2009-09-26 21:10:22 +0000
193@@ -56,25 +56,25 @@
194 Save the handler as any new presentations start here
195 """
196 self.handler, file = self.decodeMessage(message)
197- self.controllers[self.handler].loadPresentation(file)
198+ self.controllers[self.handler].load_presentation(file)
199
200 def next(self, message):
201 """
202 Based on the handler passed at startup triggers the next slide event
203 """
204- self.controllers[self.handler].nextStep()
205+ self.controllers[self.handler].next_step()
206
207 def previous(self, message):
208 """
209 Based on the handler passed at startup triggers the previous slide event
210 """
211- self.controllers[self.handler].previousStep()
212+ self.controllers[self.handler].previous_step()
213
214 def shutDown(self, message):
215 """
216 Based on the handler passed at startup triggers slide show to shut down
217 """
218- self.controllers[self.handler].closePresentation()
219+ self.controllers[self.handler].close_presentation()
220
221 def decodeMessage(self, message):
222 """
223
224=== modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
225--- openlp/plugins/presentations/lib/powerpointcontroller.py 2009-09-25 23:06:54 +0000
226+++ openlp/plugins/presentations/lib/powerpointcontroller.py 2009-09-26 21:10:22 +0000
227@@ -21,26 +21,48 @@
228 # with this program; if not, write to the Free Software Foundation, Inc., 59 #
229 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
230 ###############################################################################
231-try:
232+
233+import os
234+import logging
235+
236+if os.name == u'nt':
237 from win32com.client import Dispatch
238-except:
239- pass
240+
241+from presentationcontroller import PresentationController
242
243 # PPT API documentation:
244 # http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
245
246-class PowerPointApp(object):
247- def __init__(self):
248+class PowerpointController(PresentationController):
249+ """
250+ Class to control interactions with PowerPoint Presentations
251+ It creates the runtime Environment , Loads the and Closes the Presentation
252+ As well as triggering the correct activities based on the users input
253+ """
254+ global log
255+ log = logging.getLogger(u'PowerpointController')
256+
257+ def __init__(self, plugin):
258+ """
259+ Initialise the class
260+ """
261 log.debug(u'Initialising')
262+ PresentationController.__init__(self, plugin, u'Powerpoint')
263 self.process = None
264- self.document = None
265 self.presentation = None
266- self.startPowerpoint()
267
268- def startPowerpoint(self):
269+ def is_available(self):
270+ """
271+ PowerPoint is able to run on this machine
272+ """
273+ log.debug(u'is_available')
274+ if os.name != u'nt':
275+ return False
276 try:
277- self._app = Dispatch(u'PowerPoint.Application')
278+ self.start_process()
279+ return True
280 except:
281+<<<<<<< TREE
282 self._app = None
283 return
284 self._app.Visible = True
285@@ -165,3 +187,122 @@
286 # self.preview = w.GetClipboardData.GetData(win32con.CF_BITMAP)
287 # w.CloseClipboard()
288 return self.preview
289+=======
290+ return False
291+
292+ if os.name == u'nt':
293+ def start_process(self):
294+ """
295+ Loads PowerPoint process
296+ """
297+ self.process = Dispatch(u'PowerPoint.Application')
298+ self.process.Visible = True
299+ self.process.WindowState = 2
300+
301+ def is_loaded(self):
302+ """
303+ Returns true if a presentation is loaded
304+ """
305+ if self.process is None:
306+ return False
307+ if self.process.Windows.Count == 0:
308+ return False
309+
310+ def kill(self):
311+ self.process.Quit()
312+ self.process = None
313+
314+ def load_presentation(self, presentation):
315+ """
316+ Called when a presentation is added to the SlideController.
317+ It builds the environment, starts communcations with the background
318+ OpenOffice task started earlier. If OpenOffice is not present is is
319+ started. Once the environment is available the presentation is loaded
320+ and started.
321+
322+ ``presentation``
323+ The file name of the presentations to run.
324+ """
325+ self.filename = presentation
326+ self.process.Presentations.Open(presentation, False, False, True)
327+ self.presentation = self.process.Presentations(self.process.Presentations.Count)
328+ self.start_presentation()
329+
330+ def close_presentation(self):
331+ """
332+ Close presentation and clean up objects
333+ Triggerent by new object being added to SlideController orOpenLP
334+ being shut down
335+ """
336+ self.presentation.Close()
337+ self.presentation = None
338+
339+ def is_active(self):
340+ """
341+ Returns true if a presentation is currently active
342+ """
343+ if not self.is_loaded():
344+ return False
345+ if self.presentation.SlideShowWindow == None:
346+ return False
347+ if self.presentation.SlideShowWindow.View == None:
348+ return False
349+ return True
350+
351+ def unblank_screen(self):
352+ """
353+ Unblanks (restores) the presentationn
354+ """
355+ self.presentation.SlideShowSettings.Run()
356+ self.presentation.SlideShowWindow.View.State = 1
357+ self.presentation.SlideShowWindow.Activate()
358+
359+ def blank_screen(self):
360+ """
361+ Blanks the screen
362+ """
363+ self.presentation.SlideShowWindow.View.State = 3
364+
365+ def stop_presentation(self):
366+ """
367+ Stops the current presentation and hides the output
368+ """
369+ self.presentation.SlideShowWindow.View.Exit()
370+
371+ def start_presentation(self):
372+ """
373+ Starts a presentation from the beginning
374+ """
375+ self.presentation.SlideShowSettings.Run()
376+ rendermanager = self.plugin.render_manager
377+ rect = rendermanager.screen_list[rendermanager.current_display][u'size']
378+ self.presentation.SlideShowWindow.Top = rect.y() / 20
379+ self.presentation.SlideShowWindow.Height = rect.height() / 20
380+ self.presentation.SlideShowWindow.Left = rect.x() / 20
381+ self.presentation.SlideShowWindow.Width = rect.width() / 20
382+
383+ def get_slide_number(self):
384+ """
385+ Returns the current slide number
386+ """
387+ return self.presentation.SlideShowWindow.View.CurrentShowPosition
388+
389+ def get_slide_count(self):
390+ """
391+ Returns total number of slides
392+ """
393+ return self.presentation.Slides.Count
394+
395+ def goto_slide(self, slideno):
396+ self.presentation.SlideShowWindow.View.GotoSlide(slideno)
397+
398+ def next_step(self):
399+ self.presentation.SlideShowWindow.View.Next()
400+
401+ def previous_step(self):
402+ self.presentation.SlideShowWindow.View.Previous()
403+
404+ #def get_slide_preview_file(self, slide_no):
405+
406+
407+>>>>>>> MERGE-SOURCE
408
409=== modified file 'openlp/plugins/presentations/lib/pptviewcontroller.py'
410--- openlp/plugins/presentations/lib/pptviewcontroller.py 2009-09-25 14:36:35 +0000
411+++ openlp/plugins/presentations/lib/pptviewcontroller.py 2009-09-26 21:10:22 +0000
412@@ -22,160 +22,170 @@
413 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
414 ###############################################################################
415
416+import os
417 import logging
418
419-from ctypes import *
420-from ctypes.wintypes import RECT
421-
422-class PptviewController(object):
423+if os.name == u'nt':
424+ from ctypes import *
425+ from ctypes.wintypes import RECT
426+
427+from presentationcontroller import PresentationController
428+
429+class PptviewController(PresentationController):
430 """
431 Class to control interactions with PowerPOint Viewer Presentations
432 It creates the runtime Environment , Loads the and Closes the Presentation
433- As well as trigggering the correct activities based on the users input
434+ As well as triggering the correct activities based on the users input
435 """
436 global log
437 log = logging.getLogger(u'PptviewController')
438
439- def __init__(self):
440+ def __init__(self, plugin):
441+ """
442+ Initialise the class
443+ """
444 log.debug(u'Initialising')
445+ PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
446 self.process = None
447- self.document = None
448- self.presentation = None
449 self.pptid = None
450- self.startPPTView()
451-
452- def startPPTView(self):
453- """
454- Loads the PPTVIEWLIB library
455- """
456- log.debug(u'start PPTView')
457- self.presentation = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
458-
459- def kill(self):
460- """
461- Called at system exit to clean up any running presentations
462- """
463- log.debug(u'Kill')
464- self.closePresentation()
465-
466- def loadPresentation(self, presentation):
467- """
468- Called when a presentation is added to the SlideController.
469- It builds the environment, starts communcations with the background
470- OpenOffice task started earlier. If OpenOffice is not present is is
471- started. Once the environment is available the presentation is loaded
472- and started.
473-
474- ``presentation``
475- The file name of the presentations to run.
476- """
477- log.debug(u'LoadPresentation')
478- if self.pptid >= 0:
479- self.closePresentation()
480- rect = RECT(0, 0, 800, 600) # until such time I can get screen info
481- filename = str(presentation.replace(u'/', u'\\'));
482+ self.thumbnailpath = os.path.join(plugin.config.get_data_path(),
483+ u'pptview', u'thumbnails')
484+ self.thumbprefix = u'slide'
485+
486+ def is_available(self):
487+ """
488+ PPT Viewer is able to run on this machine
489+ """
490+ log.debug(u'is_available')
491+ if os.name != u'nt':
492+ return False
493 try:
494- tempfolder = None #r'c:\temp\pptviewlib\' + filename.split('u\\')[-1]
495- self.pptid = self.presentation.OpenPPT(filename, None, rect, tempfolder)
496+ self.start_process()
497+ return True
498 except:
499- log.exception(u'Failed to load presentation')
500- #self.slidecount = pptdll.GetSlideCount(self.pptid)
501-
502- def closePresentation(self):
503- """
504- Close presentation and clean up objects
505- Triggerent by new object being added to SlideController orOpenLP
506- being shut down
507- """
508- if self.pptid < 0:
509- return
510- self.presentation.ClosePPT(self.pptid)
511- self.pptid = -1
512-
513- def nextStep(self):
514- """
515- Triggers the next effect of slide on the running presentation
516- """
517- if self.pptid < 0:
518- return
519- self.presentation.NextStep(self.pptid)
520-
521- def previousStep(self):
522- """
523- Triggers the previous slide on the running presentation
524- """
525- if self.pptid < 0:
526- return
527- self.presentation.PrevStep(self.pptid)
528-
529- def isActive(self):
530- """
531- Returns true if a presentation is currently active
532- """
533- return self.pptid >= 0
534-
535- def resume(self):
536- """
537- Resumes a previously paused presentation
538- """
539- if self.pptid < 0:
540- return
541- self.presentation.Resume(self.pptid)
542-
543- def pause(self):
544- """
545- Not implemented (pauses a presentation)
546- """
547- return
548-
549- def blankScreen(self):
550- """
551- Blanks the screen
552- """
553- if self.pptid < 0:
554- return
555- self.presentation.Blank(self.pptid)
556-
557- def unblankScreen(self):
558- """
559- Unblanks (restores) the presentationn
560- """
561- if self.pptid < 0:
562- return
563- self.presentation.Unblank(self.pptid)
564-
565- def stop(self):
566- """
567- Stops the current presentation and hides the output
568- """
569- if self.pptid < 0:
570- return
571- self.presentation.Stop(self.pptid)
572-
573- def go(self):
574- """
575- Starts a presentation from the beginning
576- """
577- if self.pptid < 0:
578- return
579- self.presentation.RestartShow(self.pptid)
580-
581- def getSlideNumber(self):
582- """
583- Returns the current slide number
584- """
585- if self.pptid < 0:
586- return -1
587- return self.presentation.GetCurrentSlide(self.pptid)
588-
589- def setSlideNumber(self, slideno):
590- """
591- Moves to a specific slide in the presentation
592- """
593- if self.pptid < 0:
594- return
595- self.presentation.GotoSlide(self.pptid, slideno)
596-
597- slideNumber = property(getSlideNumber, setSlideNumber)
598-
599+ return False
600+
601+ if os.name == u'nt':
602+ def start_process(self):
603+ """
604+ Loads the PPTVIEWLIB library
605+ """
606+ log.debug(u'start PPTView')
607+ self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
608+
609+ def kill(self):
610+ """
611+ Called at system exit to clean up any running presentations
612+ """
613+ log.debug(u'Kill')
614+ self.close_presentation()
615+
616+ def load_presentation(self, presentation):
617+ """
618+ Called when a presentation is added to the SlideController.
619+ It builds the environment, starts communcations with the background
620+ OpenOffice task started earlier. If OpenOffice is not present is is
621+ started. Once the environment is available the presentation is loaded
622+ and started.
623+
624+ ``presentation``
625+ The file name of the presentations to run.
626+ """
627+ log.debug(u'LoadPresentation')
628+ if self.pptid >= 0:
629+ self.close_presentation()
630+ rendermanager = self.plugin.render_manager
631+ rect = rendermanager.screen_list[rendermanager.current_display][u'size']
632+ rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
633+ filename = str(presentation.replace(u'/', u'\\'));
634+ try:
635+ self.pptid = self.process.OpenPPT(filename, None, rect,
636+ str(self.thumbnailpath))
637+ except:
638+ log.exception(u'Failed to load presentation')
639+
640+ def close_presentation(self):
641+ """
642+ Close presentation and clean up objects
643+ Triggerent by new object being added to SlideController orOpenLP
644+ being shut down
645+ """
646+ self.process.ClosePPT(self.pptid)
647+ self.pptid = -1
648+
649+ def is_loaded(self):
650+ """
651+ Returns true if a presentation is loaded
652+ """
653+ return self.pptid >= 0
654+
655+ def is_active(self):
656+ """
657+ Returns true if a presentation is currently active
658+ """
659+ return self.pptid >= 0
660+
661+ def blank_screen(self):
662+ """
663+ Blanks the screen
664+ """
665+ self.process.Blank(self.pptid)
666+
667+ def unblank_screen(self):
668+ """
669+ Unblanks (restores) the presentationn
670+ """
671+ self.process.Unblank(self.pptid)
672+
673+ def stop_presentation(self):
674+ """
675+ Stops the current presentation and hides the output
676+ """
677+ self.process.Stop(self.pptid)
678+
679+ def start_presentation(self):
680+ """
681+ Starts a presentation from the beginning
682+ """
683+ self.process.RestartShow(self.pptid)
684+
685+ def get_slide_number(self):
686+ """
687+ Returns the current slide number
688+ """
689+ return self.process.GetCurrentSlide(self.pptid)
690+
691+ def get_slide_count(self):
692+ """
693+ Returns total number of slides
694+ """
695+ return self.process.GetSlideCount(self.pptid)
696+
697+ def goto_slide(self, slideno):
698+ """
699+ Moves to a specific slide in the presentation
700+ """
701+ self.process.GotoSlide(self.pptid, slideno)
702+
703+ def next_step(self):
704+ """
705+ Triggers the next effect of slide on the running presentation
706+ """
707+ self.process.NextStep(self.pptid)
708+
709+ def previous_step(self):
710+ """
711+ Triggers the previous slide on the running presentation
712+ """
713+ self.process.PrevStep(self.pptid)
714+
715+ def get_slide_preview_file(self, slide_no):
716+ """
717+ Returns an image path containing a preview for the requested slide
718+
719+ ``slide_no``
720+ The slide an image is required for, starting at 1
721+ """
722+ return os.path.join(self.thumbnailpath,
723+ self.thumbprefix + slide_no + u'.bmp')
724
725
726=== added file 'openlp/plugins/presentations/lib/presentationcontroller.py'
727--- openlp/plugins/presentations/lib/presentationcontroller.py 1970-01-01 00:00:00 +0000
728+++ openlp/plugins/presentations/lib/presentationcontroller.py 2009-09-26 21:10:22 +0000
729@@ -0,0 +1,227 @@
730+# -*- coding: utf-8 -*-
731+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
732+"""
733+OpenLP - Open Source Lyrics Projection
734+Copyright (c) 2008 Raoul Snyman
735+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
736+
737+This program is free software; you can redistribute it and/or modify it under
738+the terms of the GNU General Public License as published by the Free Software
739+Foundation; version 2 of the License.
740+
741+This program is distributed in the hope that it will be useful, but WITHOUT ANY
742+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
743+PARTICULAR PURPOSE. See the GNU General Public License for more details.
744+
745+You should have received a copy of the GNU General Public License along with
746+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
747+Place, Suite 330, Boston, MA 02111-1307 USA
748+"""
749+
750+import logging
751+
752+class PresentationController(object):
753+ """
754+ Base class for presentation controllers to inherit from
755+ Class to control interactions with presentations.
756+ It creates the runtime environment, loads and closes the presentation as
757+ well as triggering the correct activities based on the users input
758+
759+ **Basic Attributes**
760+
761+ ``name``
762+ The name that appears in the options and the media manager
763+
764+ ``plugin``
765+ The presentationplugin object
766+
767+ **Hook Functions**
768+
769+ ``kill()``
770+ Called at system exit to clean up any running presentations
771+
772+ ``is_available()``
773+ Returns True if presentation application is installed/can run on this machine
774+
775+ ``load_presentation(presentation)``
776+ Load a presentation file
777+
778+ ``close_presentation()``
779+ Close presentation and clean up objects
780+
781+ ``presentation_loaded()``
782+ Returns True if presentation is currently loaded
783+
784+ ``is_active()``
785+ Returns True if a presentation is currently running
786+
787+ ``blank_screen()``
788+ Blanks the screen, making it black.
789+
790+ ``unblank_screen()``
791+ Unblanks the screen, restoring the output
792+
793+ ``stop_presentation()``
794+ Stops the presentation, removing it from the output display
795+
796+ ``start_presentation()``
797+ Starts the presentation from the beginning
798+
799+ ``get_slide_number()``
800+ Returns the current slide number, from 1
801+
802+ ``get_slide_count()``
803+ Returns total number of slides
804+
805+ ``goto_slide(slide_no)``
806+ Jumps directly to the requested slide.
807+
808+ ``next_step()``
809+ Triggers the next effect of slide on the running presentation
810+
811+ ``previous_step()``
812+ Triggers the previous slide on the running presentation
813+
814+ ``get_slide_preview_file(slide_no)``
815+ Returns a path to an image containing a preview for the requested slide
816+
817+ """
818+ global log
819+ log = logging.getLogger(u'PresentationController')
820+ log.info(u'loaded')
821+
822+ def __init__(self, plugin=None, name=u'PresentationController'):
823+ """
824+ This is the constructor for the presentationcontroller object.
825+ This provides an easy way for descendent plugins to populate common data.
826+ This method *must* be overridden, like so::
827+
828+ class MyPresentationController(PresentationController):
829+ def __init__(self, plugin):
830+ PresentationController.__init(self, plugin, u'My Presenter App')
831+
832+ ``plugin``
833+ Defaults to *None*. The presentationplugin object
834+
835+ ``name``
836+ Name of the application, to appear in the application
837+ """
838+ self.plugin = plugin
839+ self.name = name
840+ self.start_process()
841+
842+ def is_available(self):
843+ """
844+ Presentation app is able to run on this machine
845+ """
846+ return False
847+
848+ def start_process(self):
849+ """
850+ Loads a running version of the presentation application in the background.
851+ """
852+ pass
853+
854+ def kill(self):
855+ """
856+ Called at system exit to clean up any running presentations and
857+ close the application
858+ """
859+ log.debug(u'Kill')
860+ self.close_presentation()
861+
862+ def load_presentation(self, presentation):
863+ """
864+ Called when a presentation is added to the SlideController.
865+ Loads the presentation and starts it
866+
867+ ``presentation``
868+ The file name of the presentatios to the run.
869+ """
870+ pass
871+
872+ def close_presentation(self):
873+ """
874+ Close presentation and clean up objects
875+ Triggered by new object being added to SlideController
876+ """
877+ pass
878+
879+ def is_active(self):
880+ """
881+ Returns True if a presentation is currently running
882+ """
883+ return False
884+
885+ def is_loaded(self):
886+ """
887+ Returns true if a presentation is loaded
888+ """
889+ return False
890+
891+ def blank_screen(self):
892+ """
893+ Blanks the screen, making it black.
894+ """
895+ pass
896+
897+ def unblank_screen(self):
898+ """
899+ Unblanks (restores) the presentationn
900+ """
901+ pass
902+
903+ def stop_presentation(self):
904+ """
905+ Stops the presentation, removing it from the output display
906+ """
907+ pass
908+
909+ def start_presentation(self):
910+ """
911+ Starts the presentation from the beginning
912+ """
913+ pass
914+
915+ def get_slide_number(self):
916+ """
917+ Returns the current slide number, from 1
918+ """
919+ return 0
920+
921+ def get_slide_count(self):
922+ """
923+ Returns total number of slides
924+ """
925+ return 0
926+
927+ def goto_slide(self, slide_no):
928+ """
929+ Jumps directly to the requested slide.
930+
931+ ``slide_no``
932+ The slide to jump to, starting at 1
933+ """
934+ pass
935+
936+ def next_step(self):
937+ """
938+ Triggers the next effect of slide on the running presentation
939+ This might be the next animation on the current slide, or the next slide
940+ """
941+ pass
942+
943+ def previous_step(self):
944+ """
945+ Triggers the previous slide on the running presentation
946+ """
947+ pass
948+
949+ def get_slide_preview_file(self, slide_no):
950+ """
951+ Returns an image path containing a preview for the requested slide
952+
953+ ``slide_no``
954+ The slide an image is required for, starting at 1
955+ """
956+ return None
957
958=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
959--- openlp/plugins/presentations/lib/presentationtab.py 2009-09-25 16:23:44 +0000
960+++ openlp/plugins/presentations/lib/presentationtab.py 2009-09-26 21:10:22 +0000
961@@ -31,7 +31,8 @@
962 """
963 PresentationsTab is the Presentations settings tab in the settings dialog.
964 """
965- def __init__(self):
966+ def __init__(self, controllers):
967+ self.controllers = controllers
968 SettingsTab.__init__(self,
969 translate(u'PresentationTab', u'Presentation'), u'Presentations')
970
971
972=== modified file 'openlp/plugins/presentations/presentationplugin.py'
973--- openlp/plugins/presentations/presentationplugin.py 2009-09-25 00:43:42 +0000
974+++ openlp/plugins/presentations/presentationplugin.py 2009-09-26 21:10:22 +0000
975@@ -28,14 +28,7 @@
976 from PyQt4 import QtCore, QtGui
977
978 from openlp.core.lib import Plugin
979-from openlp.plugins.presentations.lib import PresentationMediaItem, \
980- PresentationTab, ImpressController
981-if os.name == u'nt':
982- try:
983- from openlp.plugins.presentations.lib import PowerpointController
984- except:
985- pass
986- from openlp.plugins.presentations.lib import PptviewController
987+from openlp.plugins.presentations.lib import *
988
989 class PresentationPlugin(Plugin):
990
991@@ -57,7 +50,7 @@
992 """
993 Create the settings Tab
994 """
995- self.presentation_tab = PresentationTab()
996+ self.presentation_tab = PresentationTab(self.controllers)
997 return self.presentation_tab
998
999 def get_media_manager_item(self):
1000@@ -68,8 +61,8 @@
1001 self, self.icon, u'Presentations', self.controllers)
1002 return self.media_item
1003
1004- def registerControllers(self, handle, controller):
1005- self.controllers[handle] = controller
1006+ def registerControllers(self, controller):
1007+ self.controllers[controller.name] = controller
1008
1009 def check_pre_conditions(self):
1010 """
1011@@ -77,39 +70,24 @@
1012 If Not do not install the plugin.
1013 """
1014 log.debug('check_pre_conditions')
1015+ #Lets see if Powerpoint is required (Default is Not wanted)
1016+ controller = PowerpointController(self)
1017+ if int(self.config.get_config(
1018+ controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1019+ if controller.is_available():
1020+ self.registerControllers(controller)
1021 #Lets see if Impress is required (Default is Not wanted)
1022- if int(self.config.get_config(
1023- u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1024- try:
1025- if os.name == u'nt':
1026- #Check to see if we are Win32
1027- from win32com.client import Dispatch
1028- else:
1029- #Check to see if we have uno installed
1030- import uno
1031- openoffice = ImpressController()
1032- self.registerControllers(u'Impress', openoffice)
1033- except:
1034- log.exception(u'Failed to set up plugin for Impress')
1035- if os.name == u'nt':
1036- #Lets see if Powerpoint is required (Default is Not wanted)
1037- if int(self.config.get_config(
1038- u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1039- try:
1040- #Check to see if we are Win32
1041- from win32com.client import Dispatch
1042- powerpoint = PowerpointController()
1043- self.registerControllers(u'Powerpoint', powerpoint)
1044- except:
1045- log.exception(u'Failed to set up plugin for Powerpoint')
1046- #Lets see if Powerpoint Viewer is required (Default is Not wanted)
1047- if int(self.config.get_config(
1048- u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1049- try:
1050- pptview = PptviewController()
1051- self.registerControllers(u'Powerpoint Viewer', pptview)
1052- except:
1053- log.exception(u'Failed to set up plugin for Powerpoint Viewer')
1054+ controller = ImpressController(self)
1055+ if int(self.config.get_config(
1056+ controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1057+ if controller.is_available():
1058+ self.registerControllers(controller)
1059+ #Lets see if Powerpoint Viewer is required (Default is Not wanted)
1060+ controller = PptviewController(self)
1061+ if int(self.config.get_config(
1062+ controller.name, QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
1063+ if controller.is_available():
1064+ self.registerControllers(controller)
1065 #If we have no available controllers disable plugin
1066 if len(self.controllers) > 0:
1067 return True