Merge lp:~tomasgroth/openlp/ppt-catch-2.0 into lp:openlp/2.0

Proposed by Tomas Groth
Status: Merged
Approved by: Tim Bentley
Approved revision: 2206
Merged at revision: 2198
Proposed branch: lp:~tomasgroth/openlp/ppt-catch-2.0
Merge into: lp:openlp/2.0
Diff against target: 263 lines (+122/-33)
1 file modified
openlp/plugins/presentations/lib/powerpointcontroller.py (+122/-33)
To merge this branch: bzr merge lp:~tomasgroth/openlp/ppt-catch-2.0
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman Approve
Samuel Mehrbrodt Pending
Review via email: mp+224240@code.launchpad.net

This proposal supersedes a proposal from 2014-06-23.

Description of the change

Improve PowerPoint error handling

To post a comment you must log in.
Revision history for this message
Tomas Groth (tomasgroth) wrote : Posted in a previous version of this proposal

Should we try to reload the presentation if we get an error? So far I just catch the excetion to avoid the traceback window....

Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

See inline comments

review: Needs Fixing
Revision history for this message
Samuel Mehrbrodt (sam92) wrote : Posted in a previous version of this proposal

Typo (see inline comment)

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Sorry, not meaning to be nit-picky, but showing the entire traceback in the logs might be useful in future.

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

have a look in new trunk in common as I have a handler for stack traces.

That is a better fix to this but for 2.0 it may be OK but when done for 2.2 that would be the correct fix.

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
Revision history for this message
Tim Bentley (trb143) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
2--- openlp/plugins/presentations/lib/powerpointcontroller.py 2014-01-14 19:25:18 +0000
3+++ openlp/plugins/presentations/lib/powerpointcontroller.py 2014-06-24 07:03:20 +0000
4@@ -37,6 +37,7 @@
5 import pywintypes
6
7 from presentationcontroller import PresentationController, PresentationDocument
8+from openlp.core.lib.ui import UiStrings, critical_error_message_box
9
10 log = logging.getLogger(__name__)
11
12@@ -100,7 +101,7 @@
13 if self.process.Presentations.Count > 0:
14 return
15 self.process.Quit()
16- except pywintypes.com_error:
17+ except (AttributeError, pywintypes.com_error):
18 pass
19 self.process = None
20
21@@ -124,18 +125,28 @@
22 Opens the PowerPoint file using the process created earlier.
23 """
24 log.debug(u'load_presentation')
25- if not self.controller.process or not self.controller.process.Visible:
26- self.controller.start_process()
27 try:
28+ if not self.controller.process or not self.controller.process.Visible:
29+ self.controller.start_process()
30 self.controller.process.Presentations.Open(self.filepath, False,
31 False, True)
32+ self.presentation = self.controller.process.Presentations(
33+ self.controller.process.Presentations.Count)
34+ self.create_thumbnails()
35+ # Powerpoint 2013 pops up when loading a file, so we minimize it again
36+ if self.presentation.Application.Version == u'15.0':
37+ try:
38+ self.presentation.Application.WindowState = 2
39+ except:
40+ log.exception(u'Failed to minimize main powerpoint window')
41+ exc_type, exc_value, exc_traceback = sys.exc_info()
42+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
43+ return True
44 except pywintypes.com_error:
45- log.debug(u'PPT open failed')
46+ log.exception(u'PPT open failed')
47+ exc_type, exc_value, exc_traceback = sys.exc_info()
48+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
49 return False
50- self.presentation = self.controller.process.Presentations(
51- self.controller.process.Presentations.Count)
52- self.create_thumbnails()
53- return True
54
55 def create_thumbnails(self):
56 """
57@@ -187,7 +198,6 @@
58 return False
59 return True
60
61-
62 def is_active(self):
63 """
64 Returns ``True`` if a presentation is currently active.
65@@ -209,23 +219,35 @@
66 Unblanks (restores) the presentation.
67 """
68 log.debug(u'unblank_screen')
69- self.presentation.SlideShowSettings.Run()
70- self.presentation.SlideShowWindow.View.State = 1
71- self.presentation.SlideShowWindow.Activate()
72- if self.presentation.Application.Version == u'14.0':
73- # Unblanking is broken in PowerPoint 2010, need to redisplay
74- slide = self.presentation.SlideShowWindow.View.CurrentShowPosition
75- click = self.presentation.SlideShowWindow.View.GetClickIndex()
76- self.presentation.SlideShowWindow.View.GotoSlide(slide)
77- if click:
78- self.presentation.SlideShowWindow.View.GotoClick(click)
79+ try:
80+ self.presentation.SlideShowSettings.Run()
81+ self.presentation.SlideShowWindow.View.State = 1
82+ self.presentation.SlideShowWindow.Activate()
83+ if self.presentation.Application.Version == u'14.0':
84+ # Unblanking is broken in PowerPoint 2010, need to redisplay
85+ slide = self.presentation.SlideShowWindow.View.CurrentShowPosition
86+ click = self.presentation.SlideShowWindow.View.GetClickIndex()
87+ self.presentation.SlideShowWindow.View.GotoSlide(slide)
88+ if click:
89+ self.presentation.SlideShowWindow.View.GotoClick(click)
90+ except pywintypes.com_error:
91+ log.exception(u'COM error while in unblank_screen')
92+ exc_type, exc_value, exc_traceback = sys.exc_info()
93+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
94+ self.show_error_msg()
95
96 def blank_screen(self):
97 """
98 Blanks the screen.
99 """
100 log.debug(u'blank_screen')
101- self.presentation.SlideShowWindow.View.State = 3
102+ try:
103+ self.presentation.SlideShowWindow.View.State = 3
104+ except pywintypes.com_error:
105+ log.exception(u'COM error while in blank_screen')
106+ exc_type, exc_value, exc_traceback = sys.exc_info()
107+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
108+ self.show_error_msg()
109
110 def is_blank(self):
111 """
112@@ -233,7 +255,13 @@
113 """
114 log.debug(u'is_blank')
115 if self.is_active():
116- return self.presentation.SlideShowWindow.View.State == 3
117+ try:
118+ return self.presentation.SlideShowWindow.View.State == 3
119+ except pywintypes.com_error:
120+ log.exception(u'COM error while in is_blank')
121+ exc_type, exc_value, exc_traceback = sys.exc_info()
122+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
123+ return False
124 else:
125 return False
126
127@@ -242,8 +270,12 @@
128 Stops the current presentation and hides the output.
129 """
130 log.debug(u'stop_presentation')
131- self.presentation.SlideShowWindow.View.Exit()
132-
133+ try:
134+ self.presentation.SlideShowWindow.View.Exit()
135+ except pywintypes.com_error as e:
136+ log.exception(u'COM error while in stop_presentation')
137+ exc_type, exc_value, exc_traceback = sys.exc_info()
138+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
139 if os.name == u'nt':
140 def start_presentation(self):
141 """
142@@ -264,39 +296,80 @@
143 ppt_window = self.presentation.SlideShowSettings.Run()
144 if not ppt_window:
145 return
146- ppt_window.Top = rect.y() * 72 / dpi
147- ppt_window.Height = rect.height() * 72 / dpi
148- ppt_window.Left = rect.x() * 72 / dpi
149- ppt_window.Width = rect.width() * 72 / dpi
150-
151+ try:
152+ ppt_window.Top = rect.y() * 72 / dpi
153+ ppt_window.Height = rect.height() * 72 / dpi
154+ ppt_window.Left = rect.x() * 72 / dpi
155+ ppt_window.Width = rect.width() * 72 / dpi
156+ except AttributeError as e:
157+ log.exception(u'AttributeError while in start_presentation')
158+ exc_type, exc_value, exc_traceback = sys.exc_info()
159+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
160+ # Powerpoint 2013 pops up when starting a file, so we minimize it again
161+ if self.presentation.Application.Version == u'15.0':
162+ try:
163+ self.presentation.Application.WindowState = 2
164+ except:
165+ log.exception(u'Failed to minimize main powerpoint window')
166+ exc_type, exc_value, exc_traceback = sys.exc_info()
167+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
168
169 def get_slide_number(self):
170 """
171 Returns the current slide number.
172 """
173 log.debug(u'get_slide_number')
174- return self.presentation.SlideShowWindow.View.CurrentShowPosition
175+ try:
176+ ret = self.presentation.SlideShowWindow.View.CurrentShowPosition
177+ except pywintypes.com_error as e:
178+ ret = 0
179+ log.exception(u'COM error while in get_slide_number')
180+ exc_type, exc_value, exc_traceback = sys.exc_info()
181+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
182+ self.show_error_msg()
183+ return ret
184
185 def get_slide_count(self):
186 """
187 Returns total number of slides.
188 """
189 log.debug(u'get_slide_count')
190- return self.presentation.Slides.Count
191+ try:
192+ ret = self.presentation.Slides.Count
193+ except pywintypes.com_error as e:
194+ ret = 0
195+ log.exception(u'COM error while in get_slide_count')
196+ exc_type, exc_value, exc_traceback = sys.exc_info()
197+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
198+ self.show_error_msg()
199+ return ret
200
201 def goto_slide(self, slideno):
202 """
203 Moves to a specific slide in the presentation.
204 """
205 log.debug(u'goto_slide')
206- self.presentation.SlideShowWindow.View.GotoSlide(slideno)
207+ try:
208+ self.presentation.SlideShowWindow.View.GotoSlide(slideno)
209+ except pywintypes.com_error as e:
210+ log.exception(u'COM error while in goto_slide')
211+ exc_type, exc_value, exc_traceback = sys.exc_info()
212+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
213+ self.show_error_msg()
214
215 def next_step(self):
216 """
217 Triggers the next effect of slide on the running presentation.
218 """
219 log.debug(u'next_step')
220- self.presentation.SlideShowWindow.View.Next()
221+ try:
222+ self.presentation.SlideShowWindow.View.Next()
223+ except pywintypes.com_error as e:
224+ log.exception(u'COM error while in next_step')
225+ exc_type, exc_value, exc_traceback = sys.exc_info()
226+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
227+ self.show_error_msg()
228+ return
229 if self.get_slide_number() > self.get_slide_count():
230 self.previous_step()
231
232@@ -305,7 +378,13 @@
233 Triggers the previous slide on the running presentation.
234 """
235 log.debug(u'previous_step')
236- self.presentation.SlideShowWindow.View.Previous()
237+ try:
238+ self.presentation.SlideShowWindow.View.Previous()
239+ except pywintypes.com_error as e:
240+ log.exception(u'COM error while in previous_step')
241+ exc_type, exc_value, exc_traceback = sys.exc_info()
242+ log.exception(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
243+ self.show_error_msg()
244
245 def get_slide_text(self, slide_no):
246 """
247@@ -326,6 +405,16 @@
248 return _get_text_from_shapes(
249 self.presentation.Slides(slide_no).NotesPage.Shapes)
250
251+ def show_error_msg(self):
252+ """
253+ Stop presentation and display an error message.
254+ """
255+ self.stop_presentation()
256+ critical_error_message_box(UiStrings().Error, translate('PresentationPlugin.PowerpointDocument',
257+ 'An error occurred in the Powerpoint integration '
258+ 'and the presentation will be stopped. '
259+ 'Restart the presentation if you wish to present it.'))
260+
261 def _get_text_from_shapes(shapes):
262 """
263 Returns any text extracted from the shapes on a presentation slide.

Subscribers

People subscribed via source and target branches