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

Proposed by Jonathan Corwin
Status: Merged
Merged at revision: not available
Proposed branch: lp:~j-corwin/openlp/present
Merge into: lp:openlp
Diff against target: 302 lines
5 files modified
openlp/core/ui/slidecontroller.py (+31/-16)
openlp/plugins/presentations/lib/impresscontroller.py (+15/-8)
openlp/plugins/presentations/lib/messagelistener.py (+67/-9)
openlp/plugins/presentations/lib/powerpointcontroller.py (+7/-4)
openlp/plugins/presentations/lib/presentationcontroller.py (+9/-0)
To merge this branch: bzr merge lp:~j-corwin/openlp/present
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Tim Bentley Approve
Review via email: mp+12829@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jonathan Corwin (j-corwin) wrote :

Add support for first/last/blank buttons for presentations. Plus fix a few issues.

Note, this has a hardcoded 96 DPI (the most common) for positioning the powerpoint. If anyone has any ideas on how to get the actual screen DPI, please let me know.

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

Looks good and a big step forward.

review: Approve
Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
lp:~j-corwin/openlp/present updated
586. By Jonathan Corwin

Presentation updates

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/ui/slidecontroller.py'
2--- openlp/core/ui/slidecontroller.py 2009-10-01 23:43:16 +0000
3+++ openlp/core/ui/slidecontroller.py 2009-10-03 19:30:22 +0000
4@@ -269,7 +269,7 @@
5 if item.service_item_type == ServiceType.Command:
6 Receiver().send_message(u'%s_start' % item.name.lower(), \
7 [item.shortname, item.service_item_path,
8- item.service_frames[0][u'title']])
9+ item.service_frames[0][u'title'], slideno])
10 else:
11 self.displayServiceManagerItems(item, slideno)
12
13@@ -321,14 +321,23 @@
14 """
15 Go to the first slide.
16 """
17- self.PreviewListWidget.selectRow(0)
18- self.onSlideSelected()
19+ if self.commandItem.service_item_type == ServiceType.Command:
20+ Receiver().send_message(u'%s_first'% self.commandItem.name.lower())
21+ else:
22+ self.PreviewListWidget.selectRow(0)
23+ self.onSlideSelected()
24
25- def onBlankScreen(self):
26+ def onBlankScreen(self, blanked):
27 """
28 Blank the screen.
29 """
30- self.parent.mainDisplay.blankDisplay()
31+ if self.commandItem.service_item_type == ServiceType.Command:
32+ if blanked:
33+ Receiver().send_message(u'%s_blank'% self.commandItem.name.lower())
34+ else:
35+ Receiver().send_message(u'%s_unblank'% self.commandItem.name.lower())
36+ else:
37+ self.parent.mainDisplay.blankDisplay()
38
39 def onSlideSelected(self):
40 """
41@@ -337,15 +346,18 @@
42 """
43 row = self.PreviewListWidget.currentRow()
44 if row > -1 and row < self.PreviewListWidget.rowCount():
45- #label = self.PreviewListWidget.cellWidget(row, 0)
46- frame = self.serviceitem.frames[row][u'image']
47- before = time.time()
48- if frame is None:
49- frame = self.serviceitem.render_individual(row)
50- self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
51- log.info(u'Slide Rendering took %4s' % (time.time() - before))
52- if self.isLive:
53- self.parent.mainDisplay.frameView(frame)
54+ if self.commandItem.service_item_type == ServiceType.Command:
55+ Receiver().send_message(u'%s_slide'% self.commandItem.name.lower(), [row])
56+ else:
57+ #label = self.PreviewListWidget.cellWidget(row, 0)
58+ frame = self.serviceitem.frames[row][u'image']
59+ before = time.time()
60+ if frame is None:
61+ frame = self.serviceitem.render_individual(row)
62+ self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
63+ log.info(u'Slide Rendering took %4s' % (time.time() - before))
64+ if self.isLive:
65+ self.parent.mainDisplay.frameView(frame)
66
67 def onSlideSelectedNext(self):
68 """
69@@ -378,8 +390,11 @@
70 """
71 Go to the last slide.
72 """
73- self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount() - 1)
74- self.onSlideSelected()
75+ if self.commandItem.service_item_type == ServiceType.Command:
76+ Receiver().send_message(u'%s_last'% self.commandItem.name.lower())
77+ else:
78+ self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount() - 1)
79+ self.onSlideSelected()
80
81 def onStartLoop(self):
82 """
83
84=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
85--- openlp/plugins/presentations/lib/impresscontroller.py 2009-09-30 19:37:45 +0000
86+++ openlp/plugins/presentations/lib/impresscontroller.py 2009-10-03 19:30:22 +0000
87@@ -118,6 +118,7 @@
88 self.document = desktop.loadComponentFromURL(
89 url, "_blank", 0, properties)
90 self.presentation = self.document.getPresentation()
91+ self.presentation.Display = self.plugin.render_manager.current_display + 1
92 self.presentation.start()
93 self.controller = \
94 desktop.getCurrentComponent().Presentation.getController()
95@@ -178,32 +179,38 @@
96 self.document = None
97
98 def is_loaded(self):
99- return self.presentation is not None and self.document is not None
100+ return self.presentation is not None \
101+ and self.document is not None \
102+ and self.controller is not None
103
104 def is_active(self):
105 if not self.is_loaded():
106 return False
107- return self.presentation.isRunning() and self.presentation.isActive()
108+ return self.controller.isRunning() and self.controller.isActive()
109
110 def unblank_screen(self):
111- return self.presentation.resume()
112+ return self.controller.resume()
113
114 def blank_screen(self):
115- self.presentation.blankScreen(0)
116+ self.controller.blankScreen(0)
117
118 def stop_presentation(self):
119- self.presentation.deactivate()
120+ self.controller.deactivate()
121 # self.presdoc.end()
122
123 def start_presentation(self):
124- self.presentation.activate()
125+ self.controller.activate()
126+ self.goto_slide(1)
127 # self.presdoc.start()
128
129 def get_slide_number(self):
130- return self.presentation.getCurrentSlideIndex
131+ return self.controller.getCurrentSlideIndex()
132+
133+ def get_slide_count(self):
134+ return self.controller.getSlideCount()
135
136 def goto_slide(self, slideno):
137- self.presentation.gotoSlideIndex(slideno)
138+ self.controller.gotoSlideIndex(slideno-1)
139
140 def next_step(self):
141 """
142
143=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
144--- openlp/plugins/presentations/lib/messagelistener.py 2009-09-28 20:45:04 +0000
145+++ openlp/plugins/presentations/lib/messagelistener.py 2009-10-03 19:30:22 +0000
146@@ -36,19 +36,25 @@
147 def __init__(self, controllers):
148 self.controllers = controllers
149 self.handler = None
150-
151+ # messages are sent from core.ui.slidecontroller
152 QtCore.QObject.connect(Receiver.get_receiver(),
153 QtCore.SIGNAL(u'presentations_start'), self.startup)
154 QtCore.QObject.connect(Receiver.get_receiver(),
155- QtCore.SIGNAL(u'presentations_stop'), self.shutDown)
156+ QtCore.SIGNAL(u'presentations_stop'), self.shutdown)
157 QtCore.QObject.connect(Receiver.get_receiver(),
158- QtCore.SIGNAL(u'presentations_first'), self.next)
159+ QtCore.SIGNAL(u'presentations_first'), self.first)
160 QtCore.QObject.connect(Receiver.get_receiver(),
161 QtCore.SIGNAL(u'presentations_previous'), self.previous)
162 QtCore.QObject.connect(Receiver.get_receiver(),
163 QtCore.SIGNAL(u'presentations_next'), self.next)
164 QtCore.QObject.connect(Receiver.get_receiver(),
165- QtCore.SIGNAL(u'presentations_last'), self.next)
166+ QtCore.SIGNAL(u'presentations_last'), self.last)
167+ QtCore.QObject.connect(Receiver.get_receiver(),
168+ QtCore.SIGNAL(u'presentations_slide'), self.slide)
169+ QtCore.QObject.connect(Receiver.get_receiver(),
170+ QtCore.SIGNAL(u'presentations_blank'), self.blank)
171+ QtCore.QObject.connect(Receiver.get_receiver(),
172+ QtCore.SIGNAL(u'presentations_unblank'), self.unblank)
173
174 def startup(self, message):
175 """
176@@ -56,25 +62,77 @@
177 Save the handler as any new presentations start here
178 """
179 self.handler, file = self.decodeMessage(message)
180- self.controllers[self.handler].load_presentation(file)
181+ self.controller = self.controllers[self.handler]
182+ if self.controller.is_loaded():
183+ self.shutdown()
184+ self.controller.load_presentation(file)
185+
186+ def slide(self, message):
187+ #if not self.controller.is_loaded():
188+ # return
189+ #if not self.controller.is_active():
190+ # self.controller.start_presentation()
191+ self.controller.goto_slide(message[0])
192+
193+ def first(self, message):
194+ """
195+ Based on the handler passed at startup triggers the first slide
196+ """
197+ #if not self.controller.is_loaded():
198+ # return
199+ self.controller.start_presentation()
200+
201+ def last(self, message):
202+ """
203+ Based on the handler passed at startup triggers the first slide
204+ """
205+ #if not self.controller.is_loaded():
206+ # return
207+ #if not self.controller.is_active():
208+ # self.controller.start_presentation()
209+ self.controller.goto_slide(self.controller.get_slide_count())
210
211 def next(self, message):
212 """
213 Based on the handler passed at startup triggers the next slide event
214 """
215- self.controllers[self.handler].next_step()
216+ #if not self.controller.is_loaded():
217+ # return
218+ #if not self.controller.is_active():
219+ # self.controller.start_presentation()
220+ # self.controller.goto_slide(self.controller.current_slide)
221+ self.controller.next_step()
222
223 def previous(self, message):
224 """
225 Based on the handler passed at startup triggers the previous slide event
226 """
227- self.controllers[self.handler].previous_step()
228+ #if not self.controller.is_loaded():
229+ # return
230+ #if not self.controller.is_active():
231+ # self.controller.start_presentation()
232+ # self.controller.goto_slide(self.controller.current_slide)
233+ self.controller.previous_step()
234
235- def shutDown(self, message):
236+ def shutdown(self, message):
237 """
238 Based on the handler passed at startup triggers slide show to shut down
239 """
240- self.controllers[self.handler].close_presentation()
241+ self.controller.close_presentation()
242+
243+ def blank(self):
244+ #if not self.controller.is_loaded():
245+ # return
246+ #if not self.controller.is_active():
247+ # self.controller.start_presentation()
248+ self.controller.blank_screen()
249+
250+ def unblank(self):
251+ #if not self.controller.is_loaded():
252+ # return
253+ #if not self.controller.is_active():
254+ # self.controller.start_presentation()
255+ self.controller.unblank_screen()
256
257 def decodeMessage(self, message):
258 """
259
260=== modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
261--- openlp/plugins/presentations/lib/powerpointcontroller.py 2009-09-30 19:26:51 +0000
262+++ openlp/plugins/presentations/lib/powerpointcontroller.py 2009-10-03 19:30:22 +0000
263@@ -153,12 +153,15 @@
264 Starts a presentation from the beginning
265 """
266 self.presentation.SlideShowSettings.Run()
267+ self.presentation.SlideShowWindow.View.GotoSlide(1)
268 rendermanager = self.plugin.render_manager
269 rect = rendermanager.screen_list[rendermanager.current_display][u'size']
270- self.presentation.SlideShowWindow.Top = rect.y()
271- self.presentation.SlideShowWindow.Height = rect.height()
272- self.presentation.SlideShowWindow.Left = rect.x()
273- self.presentation.SlideShowWindow.Width = rect.width()
274+ dpi = 96 # This assumption is good some of the time, but not
275+ # all, but I don't know how to get the screen DPI yet
276+ self.presentation.SlideShowWindow.Top = rect.y() * 72 / dpi
277+ self.presentation.SlideShowWindow.Height = rect.height() * 72 / dpi
278+ self.presentation.SlideShowWindow.Left = rect.x() * 72 / dpi
279+ self.presentation.SlideShowWindow.Width = rect.width() * 72 / dpi
280
281 def get_slide_number(self):
282 """
283
284=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
285--- openlp/plugins/presentations/lib/presentationcontroller.py 2009-09-30 19:26:51 +0000
286+++ openlp/plugins/presentations/lib/presentationcontroller.py 2009-10-03 19:30:22 +0000
287@@ -29,6 +29,15 @@
288 It creates the runtime environment, loads and closes the presentation as
289 well as triggering the correct activities based on the users input
290
291+ To create a new controller, take a copy of this file and name it
292+ so it ends in controller.py, i.e. foobarcontroller.py
293+ Make sure it inhetits PresentationController
294+ Then fill in the blanks. If possible try and make sure it loads
295+ on all platforms, using for example os.name checks, although
296+ __init__ and check_available should always work.
297+ See impresscontroller, powerpointcontroller or pptviewcontroller
298+ for examples.
299+
300 **Basic Attributes**
301
302 ``name``