Merge lp:~marmyshev/openlp/presentation into lp:openlp

Proposed by Dmitriy Marmyshev
Status: Superseded
Proposed branch: lp:~marmyshev/openlp/presentation
Merge into: lp:openlp
Diff against target: 945 lines (+821/-5) (has conflicts)
6 files modified
openlp/core/lib/pluginmanager.py (+0/-5)
openlp/plugins/presentations/lib/keynotemaccontroller.py (+362/-0)
openlp/plugins/presentations/lib/powerpointmaccontroller.py (+401/-0)
openlp/plugins/presentations/lib/presentationtab.py (+35/-0)
openlp/plugins/presentations/presentationplugin.py (+12/-0)
scripts/check_dependencies.py (+11/-0)
Text conflict in openlp/plugins/presentations/lib/presentationtab.py
To merge this branch: bzr merge lp:~marmyshev/openlp/presentation
Reviewer Review Type Date Requested Status
matysek (community) Needs Fixing
Andreas Preikschat Pending
Review via email: mp+155063@code.launchpad.net

This proposal supersedes a proposal from 2013-03-21.

This proposal has been superseded by a proposal from 2013-04-01.

Description of the change

Add support to load presentations with PowerPoint and Keynote on Mac OS X.

To post a comment you must log in.
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

Please don't commit uncommented things. Please remove lines 10+11, 86, 112 and more.

112 + #except pywintypes.com_error:
113 + except:

Don't commit the uncommented line. You should catch the generic exception (I don't know why you commented except pywintypes.com_error out). Also you should log that you cought an exception.

Line 123: Should be openlp_settings = Settings(u'openlp.org', u'OpenLP')
We use u'' for strings. And you missed the space after the comma.

Line 127: You have two spaces there (should be just one)

Line 128 (and some more): Don't use <>, rather use != for inequality.

And please add some more comments. Regards

PS: Unable to test the code here, as I don't have a MAC

review: Needs Fixing
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Will need to be approved by matysek_

Revision history for this message
matysek (mzibricky) wrote : Posted in a previous version of this proposal

> Will need to be approved by matysek_

I will need to test it.

Could you please add the 'appscript' osx dependency to the following script?

./scripts/check_dependencies.py

Thanks

Revision history for this message
matysek (mzibricky) wrote : Posted in a previous version of this proposal

I tested the branch and trying to load a presentation in openlp. MS powerpoint is started with openlp.

These are the issues I get:
- when the user quits manually powerpoint before exiting openlp - powerpoint is started again after openlp exits.
- when trying to load a ppt presentation - .ppt file is loaded into powerpoint but new presentation item is not added to openlp and I get the following exception:

cat openlp_trace.txt
 --- Exception Traceback ---
Traceback (most recent call last):
  File "/Users/martin/Documents/openlp/bug-836574/openlp/core/lib/mediamanageritem.py", line 334, in onFileClick
    self.validateAndLoad(files)
  File "/Users/martin/Documents/openlp/bug-836574/openlp/core/lib/mediamanageritem.py", line 383, in validateAndLoad
    self.loadList(full_list)
  File "/Users/martin/Documents/openlp/bug-836574/openlp/plugins/presentations/lib/mediaitem.py", line 188, in loadList
    doc.load_presentation()
  File "/Users/martin/Documents/openlp/bug-836574/openlp/plugins/presentations/lib/powerpointmaccontroller.py", line 153, in load_presentation
    self.create_thumbnails()
  File "/Users/martin/Documents/openlp/bug-836574/openlp/plugins/presentations/lib/powerpointmaccontroller.py", line 175, in create_thumbnails
    for filename in os.listdir(temp_dir):
OSError: [Errno 2] No such file or directory: '/Users/martin/Library/Application Support/openlp/Data/presentations/thumbnails/Chapter08.ppt/Chapter08.ppt'

--- System information ---
Platform: Darwin-11.4.2-x86_64-i386-64bit

--- Library Versions ---
Python: 2.7.3
Qt4: 4.8.4
Phonon: 4.6.0
PyQt4: 4.9.6
QtWebkit: 534.34
SQLAlchemy: 0.7.9
SQLAlchemy Migrate: 0.7.2
BeautifulSoup: 3.2.1
lxml: 2.3.2
Chardet: 2.0.1
PyEnchant: 1.6.5
PySQLite: -
Mako: 0.7.3
pyUNO bridge: -

Revision history for this message
matysek (mzibricky) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

Just a note: when you are ready with your changes (fixed) which were requested then resubmit your proposal (upper-left corner -> Resubmit proposal). Then the developers know that your code base is again read to be reviewed.

Keep it up :)

Revision history for this message
matysek (mzibricky) wrote : Posted in a previous version of this proposal

Today I tested the r2118 - the temp_dir check and relaunching ppt are fixed.

There are some other issues:

- when opening a presentation the preview of the 1st slide is not generated in openlp. Last time it was created.
- What is the use case scenario when the powerpoint should be started?
  - Should it start directly with openlp when enabled and powerpoint is installed?
  - Or start it later when .ppt file is imported?
  - now it sometimes start with openlp
  - when powerpoint is started with openlp it is put above openlp window and openlp is thus hidden
- powerpoint and openlp icon is not visible in the dock bar - last time there were visible both.
- when a .ppt file is opened and I click on the preview button - powerpoint window takes focus and is put above openlp. But then in openlp i get message like

  "The presentation /Users/martin/Downloads/lecture22.ppt is incomplete, please reload."

Revision history for this message
Dmitriy Marmyshev (marmyshev) wrote : Posted in a previous version of this proposal

Yes, matysek, the work with PPT on Mac OS is really really hard.

There are some other issues with it:
for example, if your are in slideshow mode (with presenter view) and switch
to another app - PPT hide slideshow window from second screen. or if you
send command to PPT "Next slide" or "Go to slide N" the PPT wont do this
until you activate the PPT app.
If you use "full screen" mode (without presenter view) on second screen the
PPT app change global settings of display to "Mirror displays" and after
slideshow exits the PPT app change displays back to "extention" mode.
As it seems, the behavior of PPT will be different then on Windows platform.
I also analyzed other applications (like ProPresenter, Mediashout, new
EasyWorship) they have the same issue. They solve it in two ways:
1st - convert PPT file to its own slide's format and forget about MS PPT
forever.
2nd - use MS PPT app on Mac as launched app from their app - by sending
command (as i do) to MS PPT to start slideshow with .ppt file from service
schedule. and all controlling continuing in MS PPT, after MS PPT finish
slideshow the controlling of second screen returns back to their app.

I think, the best we can do - is the 2nd way.

Almost the same is for Keynote app controller.

So, I want to change the behavior of mac-controllers and then will propose
to merge again.

On Tue, Feb 12, 2013 at 2:03 AM, matysek <email address hidden> wrote:

> Today I tested the r2118 - the temp_dir check and relaunching ppt are
> fixed.
>
> There are some other issues:
>
> - when opening a presentation the preview of the 1st slide is not
> generated in openlp. Last time it was created.
> - What is the use case scenario when the powerpoint should be started?
> - Should it start directly with openlp when enabled and powerpoint is
> installed?
> - Or start it later when .ppt file is imported?
> - now it sometimes start with openlp
> - when powerpoint is started with openlp it is put above openlp window
> and openlp is thus hidden
> - powerpoint and openlp icon is not visible in the dock bar - last time
> there were visible both.
> - when a .ppt file is opened and I click on the preview button -
> powerpoint window takes focus and is put above openlp. But then in openlp i
> get message like
>
> "The presentation /Users/martin/Downloads/lecture22.ppt is incomplete,
> please reload."
> --
> https://code.launchpad.net/~marmyshev/openlp/presentation/+merge/143389
> You are the owner of lp:~marmyshev/openlp/presentation.
>

Revision history for this message
Jonathan Corwin (j-corwin) wrote : Posted in a previous version of this proposal

You may have tried this, but is it possible to re-activate the PowerPoint window prior to sending the commands? There looks to be some "Activate" applescript command to do this?

Revision history for this message
Dmitriy Marmyshev (marmyshev) wrote : Posted in a previous version of this proposal

Yes, now I use "Activate()" command for changing slides in PPT, but this
looks ugly.
This is not understandable for user's mind.

And also Keynote has the same problem as PPT - if you activate another app
during slideshow it hides slideshow window from second screen.

On Wed, Feb 13, 2013 at 2:58 PM, Jonathan Corwin <email address hidden> wrote:

> You may have tried this, but is it possible to re-activate the PowerPoint
> window prior to sending the commands? There looks to be some "Activate"
> applescript command to do this?
> --
> https://code.launchpad.net/~marmyshev/openlp/presentation/+merge/143389
> You are the owner of lp:~marmyshev/openlp/presentation.
>

Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

Any progress on this?

Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

- You have a conflict in 'openlp/plugins/presentations/lib/presentationtab.py'

This
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
should be
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
We moved from 80 characters to 120.

Please do not add commented lines (e. g. 207, 221, ...).

review: Needs Fixing
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

If you need help or have any questions in regard to my comments feel free to ask. :)

Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

Please do not do this:
55 +from appscript import *
rather do
import appscript

59 +
60 +log = logging.getLogger(__name__)
61 +
62 +class KeynoteController(PresentationController)
Before and after the "log = " should be two blank lines

106 + if self.process and len(self.process.slideshows()) > 0:
When dealing with lists do "if not my_list" instead of "if len(my_list) > 0"

387 + text = ''
391 + text += shape.TextFrame.TextRange.Text + '\n'
If not explicit wanted do not use strings; use unicode strings: u''

review: Needs Fixing
Revision history for this message
matysek (mzibricky) wrote :

I'm testing it with macoffice 2011 but:
- the macoffice is not recognized by openl
- all the presentation controllers are greyed out in properties
- in the log there is a text like

2013-03-23 13:22:37,125 presentationplugin INFO Presentations Initialising
2013-03-23 13:22:37,140 openlp.plugins.presentations.lib.keynotemaccontroller DEBUG check_available
2013-03-23 13:22:37,140 openlp.plugins.presentations.lib.impresscontroller DEBUG check_available
2013-03-23 13:22:37,141 openlp.plugins.presentations.lib.powerpointmaccontroller DEBUG check_available
2013-03-23 13:22:37,141 openlp.plugins.presentations.lib.pptviewcontroller DEBUG check_available
2013-03-23 13:22:37,142 openlp.core.ui.mediadockmanager DEBUG Inserting Presentations dock
2013-03-23 13:22:37,145 openlp.plugins.presentations.lib.keynotemaccontroller DEBUG start_process
2013-03-23 13:22:37,146 presentationplugin WARNING Failed to start controller process
2013-03-23 13:22:37,146 openlp.plugins.presentations.lib.powerpointmaccontroller DEBUG start_process
2013-03-23 13:22:37,146 presentationplugin WARNING Failed to start controller process
2013-03-23 13:22:37,148 openlp.core.lib.pluginmanager INFO Initialisation Complete for presentations

review: Needs Information
Revision history for this message
matysek (mzibricky) wrote :

It's probably not working because with our latest style fixes you replaced
  from appscript import *
with
  import appscript

However, you should then also add prefix appscript to the objects you use from that module like

  appscript.app
  appscript.k
  appscript.CantLaunchApplicationError

463 + def check_available(self):
464 + """
465 + PowerPoint is able to run on this machine
466 + """
467 + log.debug(u'check_available')
468 + return True

Is there a better way to check availability of powerpoint than only return true?
- probably try to create process by appscript.app() and catch for error appscript.ApplicationNotFoundError

When I add .ppt file to openlp and click on the 'preview'button I get message like

  'The Presentation file.ppt is incomplete, please reload.'

review: Needs Fixing
lp:~marmyshev/openlp/presentation updated
2122. By Dmitriy Marmyshev

returned back appscript import.

Revision history for this message
Dmitriy Marmyshev (marmyshev) wrote :

I returned back the import. Probably it's temperary.
Please, try all other behaviors of controllers.

lp:~marmyshev/openlp/presentation updated
2123. By Dmitriy Marmyshev

improvements of commands to ppt and keynote applications

2124. By Dmitriy Marmyshev

appscript import fix and keynote create_thumbnails fix

2125. By Dmitriy Marmyshev

HEAD

2126. By Dmitriy Marmyshev

next_step and previous_step fixes

2127. By Dmitriy Marmyshev

activate presentation in firsttimeform and firsttimewizard.

2128. By Dmitriy Marmyshev

logs added.

2129. By Dmitriy Marmyshev

removed commented lines

2130. By Dmitriy Marmyshev

Trunk

2131. By Dmitriy Marmyshev

temp new chreate_thumbnails. Needs to fix

2132. By Dmitriy Marmyshev

Trunk

2133. By Dmitriy Marmyshev

p3 fixes

2134. By Dmitriy Marmyshev

Trunk

2135. By Dmitriy Marmyshev

fixes unicode & bzr eric5 ignore

2136. By Dmitriy Marmyshev

Trunk

2137. By Dmitriy Marmyshev

thumbnail fixes

2138. By Dmitriy Marmyshev

Tests

2139. By Dmitriy Marmyshev

Added check_ver for appscript module

2140. By Dmitriy Marmyshev

Trunk

2141. By Dmitriy Marmyshev

cleanups.

2142. By Dmitriy Marmyshev

Trunk

2143. By Dmitriy Marmyshev

tests fixes

Unmerged revisions

2143. By Dmitriy Marmyshev

tests fixes

2142. By Dmitriy Marmyshev

Trunk

2141. By Dmitriy Marmyshev

cleanups.

2140. By Dmitriy Marmyshev

Trunk

2139. By Dmitriy Marmyshev

Added check_ver for appscript module

2138. By Dmitriy Marmyshev

Tests

2137. By Dmitriy Marmyshev

thumbnail fixes

2136. By Dmitriy Marmyshev

Trunk

2135. By Dmitriy Marmyshev

fixes unicode & bzr eric5 ignore

2134. By Dmitriy Marmyshev

Trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/lib/pluginmanager.py'
--- openlp/core/lib/pluginmanager.py 2013-03-19 19:43:22 +0000
+++ openlp/core/lib/pluginmanager.py 2013-04-01 23:08:22 +0000
@@ -94,11 +94,6 @@
94 present_plugin_dir = os.path.join(self.base_path, 'presentations')94 present_plugin_dir = os.path.join(self.base_path, 'presentations')
95 log.debug(u'finding plugins in %s at depth %d', unicode(self.base_path), start_depth)95 log.debug(u'finding plugins in %s at depth %d', unicode(self.base_path), start_depth)
96 for root, dirs, files in os.walk(self.base_path):96 for root, dirs, files in os.walk(self.base_path):
97 if sys.platform == 'darwin' and root.startswith(present_plugin_dir):
98 # TODO Presentation plugin is not yet working on Mac OS X.
99 # For now just ignore it. The following code will ignore files from the presentation plugin directory
100 # and thereby never import the plugin.
101 continue
102 for name in files:97 for name in files:
103 if name.endswith(u'.py') and not name.startswith(u'__'):98 if name.endswith(u'.py') and not name.startswith(u'__'):
104 path = os.path.abspath(os.path.join(root, name))99 path = os.path.abspath(os.path.join(root, name))
105100
=== added file 'openlp/plugins/presentations/lib/keynotemaccontroller.py'
--- openlp/plugins/presentations/lib/keynotemaccontroller.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/presentations/lib/keynotemaccontroller.py 2013-04-01 23:08:22 +0000
@@ -0,0 +1,362 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2012 Raoul Snyman #
8# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
9# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
10# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, #
11# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
12# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
13# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
14# Frode Woldsund, Martin Zibricky #
15# --------------------------------------------------------------------------- #
16# This program is free software; you can redistribute it and/or modify it #
17# under the terms of the GNU General Public License as published by the Free #
18# Software Foundation; version 2 of the License. #
19# #
20# This program is distributed in the hope that it will be useful, but WITHOUT #
21# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
22# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
23# more details. #
24# #
25# You should have received a copy of the GNU General Public License along #
26# with this program; if not, write to the Free Software Foundation, Inc., 59 #
27# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
28###############################################################################
29
30import os
31import sys
32import logging
33import mactypes
34
35import appscript
36
37from openlp.core.lib import Settings, ScreenList
38from presentationcontroller import PresentationController, PresentationDocument
39
40
41log = logging.getLogger(__name__)
42
43
44class KeynoteController(PresentationController):
45 """
46 Class to control interactions with KeyNote Presentations
47 It creates the runtime Environment , Loads the and Closes the Presentation
48 As well as triggering the correct activities based on the users input
49 """
50 log.info(u'KeynoteController loaded')
51
52 def __init__(self, plugin):
53 """
54 Initialise the class
55 """
56 log.debug(u'Initialising')
57 PresentationController.__init__(self, plugin, u'Keynote', KeynoteDocument)
58 self.supports = [u'key']
59 self.process = None
60
61 def check_available(self):
62 """
63 KeyNote is able to run on this machine
64 """
65 log.debug(u'check_available')
66 try:
67 self.process = appscript.app('Keynote')
68 except appscript.ApplicationNotFoundError:
69 return False
70 self.kill()
71 return True
72
73 def start_process(self):
74 """
75 Loads KeyNote process
76 """
77 log.debug(u'start_process')
78 if not self.process or not self.process.isrunning():
79 self.process = appscript.app('Keynote')
80 self.process.relaunchmode = 'limited' #'always'
81 self.process.launch()
82 self.apply_app_settings()
83
84 def kill(self):
85 """
86 Called at system exit to clean up any running presentations
87 """
88 log.debug(u'Kill Keynote')
89 while self.docs and self.process.isrunning():
90 self.docs[0].close_presentation()
91 if self.process is None or not self.process.isrunning():
92 return
93 try:
94 total = self.process.slideshows()
95 if self.process and total != appscript.k.missing_value and len(total) > 0:
96 return
97 self.process.quit(saving = appscript.k.ask)
98 except appscript.CantLaunchApplicationError:
99 pass
100 self.process = None
101
102 def apply_app_settings(self):
103 """
104 Apply settings for Keynote
105 PresentationModeEnableFeedbackDisplay = True if in settings of OpenLP show presenter view = True
106 PresentationModeUseSecondary = 1 if OpenLP monitor for output = Screen 2
107 """
108 openlp_settings = Settings(u'openlp.org',u'OpenLP')
109 keynote_settings = Settings(u'apple', u'iWork.Keynote')
110 use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary'))
111 monitor = openlp_settings.value( u'general/monitor')
112 override_position = openlp_settings.value( u'general/override position')
113 if not override_position and use_secondary != monitor:
114 keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor))
115 elif override_position and use_secondary != 0:
116 keynote_settings.setValue(u'PresentationModeUseSecondary', u'0')
117 show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view')
118 keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay')
119 if show_presenter_view != keynote_feedback_display:
120 keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view)
121 play_well_with_others = keynote_settings.value(u'PresentationModePlayWellWithOthers')
122 if not play_well_with_others:
123 keynote_settings.setValue(u'PresentationModePlayWellWithOthers', True)
124
125
126class KeynoteDocument(PresentationDocument):
127 """
128 Class which holds information and controls a single presentation
129 """
130
131 def __init__(self, controller, presentation):
132 """
133 Constructor, store information about the file and initialise
134 """
135 log.debug(u'Init Presentation Keynote')
136 PresentationDocument.__init__(self, controller, presentation)
137 self.presentation = None
138
139 def load_presentation(self):
140 """
141 Called when a presentation is added to the SlideController.
142 Opens the Keynote file using the process created earlier.
143 """
144 log.debug(u'load_presentation')
145 if not self.controller.process or not self.controller.process.isrunning():
146 self.controller.start_process()
147 try:
148 self.controller.process.open(self.filepath)
149 except appscript.CommandError:
150 log.debug(u'Keynote open failed')
151 return False
152 slideshows = self.controller.process.slideshows()
153 for slideshow in slideshows:
154 path = slideshow.path()
155 if self.filepath == path:
156 self.presentation = slideshow
157 self.create_thumbnails()
158 return True
159 self.presentation = None
160 return False
161
162 def create_thumbnails(self):
163 """
164 Create the thumbnail images for the current presentation.
165 """
166 log.debug(u'create_thumbnails')
167 if self.check_thumbnails():
168 return
169 thumbnail_folder = self.get_thumbnail_folder()
170 if not os.path.exists(thumbnail_folder):
171 os.makedirs(thumbnail_folder)
172 try:
173 self.controller.process.open(self.filepath)
174 except appscript.CommandError:
175 log.debug(u'KeyNote open failed')
176 return
177 temp_dir = self.controller.thumbnail_folder
178 keystroke = os.path.join(temp_dir, u'temp' + self.controller.thumbnail_prefix)
179 self.controller.process.activate()
180 appscript.app(u'System Events').processes[u'Keynote'].menu_bars[1].menu_bar_items[3].menus.menu_items[11].click()
181 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].tool_bars.buttons[4].click()
182 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].radio_groups[1].radio_buttons[1].click()
183 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1].click()
184 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1]\
185 .menus.menu_items[2].click()
186 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[2].click()
187 appscript.app(u'System Events').processes[u'Keynote'].keystroke(keystroke)
188 appscript.app(u'System Events').processes[u'Keynote'].key_code(36)
189 appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[1].click()
190 self.controller.plugin._main_window.activateWindow()
191 slide_no = 0
192 for filename in os.listdir(temp_dir):
193 full_filename = os.path.join(temp_dir, filename)
194 if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png':
195 continue
196 slide_no = slide_no + 1
197 if not filename.startswith(self.controller.thumbnail_prefix):
198 path = os.path.join(thumbnail_folder,
199 self.controller.thumbnail_prefix + unicode(slide_no) + u'.png')
200 try:
201 os.rename(full_filename, path)
202 except:
203 open(path,'w').write(open(full_filename,'r').read())
204 os.unlink(full_filename)
205
206 def close_presentation(self):
207 """
208 Close presentation and clean up objects. This is triggered by a new
209 object being added to SlideController or OpenLP being shut down.
210 """
211 log.debug(u'ClosePresentation')
212 if self.presentation:
213 try:
214 self.presentation.close()
215 except appscript.CommandError:
216 pass
217 self.presentation = None
218 self.controller.remove_doc(self)
219
220 def is_loaded(self):
221 """
222 Returns ``True`` if a presentation is loaded.
223 """
224 log.debug(u'is_loaded')
225 try:
226 if not self.controller.process.isrunning():
227 return False
228 windows = self.controller.process.windows()
229 if len(windows) == 0:
230 return False
231 slideshows = self.controller.process.slideshows()
232 if len(slideshows) == 0:
233 return False
234 except:
235 return False
236 for slideshow in slideshows:
237 path = slideshow.path()
238 if self.filepath == path:
239 return True
240 return False
241
242 def is_active(self):
243 """
244 Returns ``True`` if a presentation is currently active.
245 """
246 log.debug(u'is_active')
247 if not self.is_loaded():
248 return False
249 try:
250 if not self.presentation.playing():
251 return False
252 except appscript.CommandError:
253 return False
254 return True
255
256 def unblank_screen(self):
257 """
258 Unblanks (restores) the presentation.
259 """
260 log.debug(u'unblank_screen')
261 if self.is_blank():
262 slef.presentation.start_presentation()
263
264 def blank_screen(self):
265 """
266 Blanks the screen.
267 """
268 log.debug(u'blank_screen')
269 self.presentation.stop_slideshow()
270
271 def is_blank(self):
272 """
273 Returns ``True`` if screen is blank.
274 """
275 log.debug(u'is_blank')
276 if self.is_active():
277 return not self.presentation.playing()
278 else:
279 return False
280
281 def stop_presentation(self):
282 """
283 Stops the current presentation and hides the output.
284 """
285 log.debug(u'stop_presentation')
286 self.presentation.stop_slideshow()
287
288
289 def start_presentation(self):
290 """
291 Starts a presentation from the beginning.
292 """
293 log.debug(u'start_presentation')
294 if not self.is_active():
295 self.controller.apply_app_settings()
296 try:
297 self.presentation.start()
298 except appscript.CommandError:
299 return
300 rect = ScreenList().current[u'size']
301 top = rect.y()
302 height = rect.height()
303 left_position = rect.x()
304 width = rect.width()
305 self.controller.process.windows[1].bounds.set([left_position, top, left_position + width, top + height])
306
307 def get_slide_number(self):
308 """
309 Returns the current slide number.
310 """
311 log.debug(u'get_slide_number')
312 return self.presentation.current_slide().slide_number()
313
314 def get_slide_count(self):
315 """
316 Returns total number of slides.
317 """
318 log.debug(u'get_slide_count')
319 slides = self.presentation.slides()
320 return len(slides)
321
322 def goto_slide(self, slideno):
323 """
324 Moves to a specific slide in the presentation.
325 """
326 log.debug(u'goto_slide')
327 slide = self.presentation.slides()[slideno-1]
328 self.presentation.show(slide)
329
330 def next_step(self):
331 """
332 Triggers the next effect of slide on the running presentation.
333 """
334 log.debug(u'next_step')
335 self.presentation.show_next()
336 if self.get_slide_number() > self.get_slide_count():
337 self.previous_step()
338
339 def previous_step(self):
340 """
341 Triggers the previous slide on the running presentation.
342 """
343 log.debug(u'previous_step')
344 self.presentation.show_previous()
345
346 def get_slide_text(self, slide_no):
347 """
348 Returns the text on the slide.
349
350 ``slide_no``
351 The slide the text is required for, starting at 1.
352 """
353 return self.presentation.slides[slide_no].body
354
355 def get_slide_notes(self, slide_no):
356 """
357 Returns the text on the slide.
358
359 ``slide_no``
360 The slide the notes are required for, starting at 1.
361 """
362 return self.presentation.slides[slide_no].notes
0363
=== added file 'openlp/plugins/presentations/lib/powerpointmaccontroller.py'
--- openlp/plugins/presentations/lib/powerpointmaccontroller.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/presentations/lib/powerpointmaccontroller.py 2013-04-01 23:08:22 +0000
@@ -0,0 +1,401 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2012 Raoul Snyman #
8# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
9# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
10# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, #
11# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
12# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
13# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
14# Frode Woldsund, Martin Zibricky #
15# --------------------------------------------------------------------------- #
16# This program is free software; you can redistribute it and/or modify it #
17# under the terms of the GNU General Public License as published by the Free #
18# Software Foundation; version 2 of the License. #
19# #
20# This program is distributed in the hope that it will be useful, but WITHOUT #
21# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
22# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
23# more details. #
24# #
25# You should have received a copy of the GNU General Public License along #
26# with this program; if not, write to the Free Software Foundation, Inc., 59 #
27# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
28###############################################################################
29
30import os
31import sys
32import logging
33import shutil
34import mactypes
35
36import appscript
37
38from openlp.core.lib import Settings, ScreenList
39from presentationcontroller import PresentationController, PresentationDocument
40
41
42log = logging.getLogger(__name__)
43
44
45class PowerpointController(PresentationController):
46 """
47 Class to control interactions with PowerPoint Presentations
48 It creates the runtime Environment , Loads the and Closes the Presentation
49 As well as triggering the correct activities based on the users input
50 """
51 log.info(u'PowerpointController loaded')
52
53 def __init__(self, plugin):
54 """
55 Initialise the class
56 """
57 log.debug(u'Initialising')
58 PresentationController.__init__(self, plugin, u'Powerpoint', PowerpointDocument)
59 self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
60 self.process = None
61
62 def check_available(self):
63 """
64 PowerPoint is able to run on this machine
65 """
66 log.debug(u'check_available')
67 try:
68 self.process = appscript.app(id='com.microsoft.powerpoint')
69 except appscript.ApplicationNotFoundError:
70 return False
71 self.kill()
72 return True
73
74 def start_process(self):
75 """
76 Loads PowerPoint process
77 """
78 log.debug(u'start_process')
79 if not self.process or not self.process.isrunning():
80 self.process = appscript.app(id='com.microsoft.powerpoint')
81 self.process.relaunchmode = 'limited' #'always'
82 self.process.launch()
83 self.apply_app_settings()
84
85 def kill(self):
86 """
87 Called at system exit to clean up any running presentations
88 """
89 log.debug(u'Kill Powerpoint')
90 while self.docs and self.process.isrunning():
91 self.docs[0].close_presentation()
92 if self.process is None or not self.process.isrunning():
93 return
94 try:
95 total = self.process.presentations()
96 if self.process and total != appscript.k.missing_value and len(total) > 0:
97 return
98 self.process.quit(saving = appscript.k.ask)
99 except appscript.CantLaunchApplicationError:
100 pass
101 self.process = None
102
103 def apply_app_settings(self):
104 """
105 Apply settings for PowerPoint
106 14\Options\Options\Save graphics screen heigth = 240
107 14\Options\Options\Save graphics screen width = 320
108 14\Options\Options\Save only current slide graphics = 0
109
110 """
111 openlp_settings = Settings("openlp.org","OpenLP")
112 ppt_settings = Settings("Microsoft", "Powerpoint")
113# use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary', u''))
114# monitor = openlp_settings.value( u'general/monitor', 0)
115# display_on_monitor = openlp_settings.value( u'general/display on monitor', False)
116# if display_on_monitor and use_secondary != monitor:
117# keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor))
118# elif not display_on_monitor and use_secondary > 0:
119# keynote_settings.setValue(u'PresentationModeUseSecondary', u'0')
120# show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view', False)
121# keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay', False)
122# if show_presenter_view != keynote_feedback_display:
123# keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view)
124
125
126class PowerpointDocument(PresentationDocument):
127 """
128 Class which holds information and controls a single presentation
129 """
130
131 def __init__(self, controller, presentation):
132 """
133 Constructor, store information about the file and initialise
134 """
135 log.debug(u'Init Presentation Powerpoint')
136 PresentationDocument.__init__(self, controller, presentation)
137 self.presentation = None
138
139 def load_presentation(self):
140 """
141 Called when a presentation is added to the SlideController.
142 Opens the PowerPoint file using the process created earlier.
143 """
144 log.debug(u'load_presentation')
145 if not self.controller.process or not self.controller.process.isrunning():
146 self.controller.start_process()
147 try:
148 self.controller.process.open(self.filepath)
149 except appscript.CommandError:
150 log.debug(u'PPT open failed')
151 return False
152 presentations = self.controller.process.presentations()
153 for presentation in presentations:
154 full_name = presentation.full_name()
155 full_name = full_name.replace(u'Macintosh HD', u'')
156 full_name = full_name.replace(u':', u'/')
157 if self.filepath == full_name:
158 self.presentation = presentation
159 self.create_thumbnails()
160 return True
161 return False
162
163 def create_thumbnails(self):
164 """
165 Create the thumbnail images for the current presentation.
166 """
167 log.debug(u'create_thumbnails')
168 if self.check_thumbnails():
169 return
170 thumbnail_folder = self.get_thumbnail_folder()
171 self.presentation.save(in_ = thumbnail_folder, as_ = appscript.k.save_as_PNG)
172 slide_no = 0
173 temp_dir = os.path.join(thumbnail_folder, self.get_file_name())
174 if not os.path.isdir(temp_dir):
175# log.debug(u'create_thumbnails failed')
176 temp_dir = thumbnail_folder
177 for filename in os.listdir(temp_dir):
178 full_filename = os.path.join(temp_dir, filename)
179 if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png':
180 continue
181 slide_no = slide_no + 1
182 if not filename.startswith(self.controller.thumbnail_prefix):
183 path = os.path.join(thumbnail_folder,
184 self.controller.thumbnail_prefix + unicode(slide_no) + u'.png')
185 try:
186 os.rename(full_filename, path)
187 except:
188 open(path,'w').write(open(full_filename,'r').read())
189 os.unlink(full_filename)
190 if temp_dir != thumbnail_folder:
191 try:
192 shutil.rmtree(temp_dir)
193 except:
194 pass
195
196 def close_presentation(self):
197 """
198 Close presentation and clean up objects. This is triggered by a new
199 object being added to SlideController or OpenLP being shut down.
200 """
201 log.debug(u'ClosePresentation')
202 if self.presentation:
203 try:
204 self.presentation.close()
205 except appscript.CommandError:
206 pass
207 self.presentation = None
208 self.controller.remove_doc(self)
209
210 def is_loaded(self):
211 """
212 Returns ``True`` if a presentation is loaded.
213 """
214 log.debug(u'is_loaded')
215 try:
216 if not self.controller.process.isrunning():
217 return False
218 if len(self.controller.process.document_windows()) == 0:
219 return False
220 presentations = self.controller.process.presentations()
221 if len(presentations) == 0:
222 return False
223 except:
224 return False
225 for presentation in presentations:
226 full_name = presentation.full_name()
227 full_name = full_name.replace(u'Macintosh HD', u'')
228 full_name = full_name.replace(u':', u'/')
229 if self.filepath == full_name:
230 return True
231 return False
232
233 def is_active(self):
234 """
235 Returns ``True`` if a presentation is currently active.
236 """
237 log.debug(u'is_active')
238 if not self.is_loaded():
239 return False
240 try:
241 slide_show_window = self.presentation.slide_show_window
242 if slide_show_window is None:
243 return False
244 slide_state = self.presentation.slide_show_window.slideshow_view.slide_state()
245 if slide_state is None or slide_state == appscript.k.missing_value:
246 return False
247 except:
248 return False
249 return True
250
251 def unblank_screen(self):
252 """
253 Unblanks (restores) the presentation.
254 """
255 log.debug(u'unblank_screen')
256 if self.is_blank():
257 settings = self.presentation.slide_show_settings
258 #settings.run_slide_show()
259 self.presentation.slide_show_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_running)
260 self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
261 self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
262
263 def blank_screen(self):
264 """
265 Blanks the screen.
266 """
267 log.debug(u'blank_screen')
268 self.presentation.slide_show_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_black_screen)
269
270 def is_blank(self):
271 """
272 Returns ``True`` if screen is blank.
273 """
274 log.debug(u'is_blank')
275 if self.is_active() and self.presentation.slide_show_window.slideshow_view\
276 .slide_state() is appscript.k.slide_show_state_black_screen:
277 return True
278 else:
279 return False
280
281 def stop_presentation(self):
282 """
283 Stops the current presentation and hides the output.
284 """
285 log.debug(u'stop_presentation')
286 self.presentation.slide_show_window.slideshow_view.exit_slide_show()
287
288
289 def start_presentation(self):
290 """
291 Starts a presentation from the beginning.
292 """
293 log.debug(u'start_presentation')
294 rect = ScreenList().current[u'size']
295 ppt_settings = self.presentation.slide_show_settings
296 openlp_settings = Settings("openlp.org","OpenLP")
297 show_presenter_view = openlp_settings.value(self.controller.plugin.settingsSection + u'/show presenter view')
298 override_position = openlp_settings.value( u'general/override position')
299 if show_presenter_view:
300 ppt_settings.show_type.set(appscript.k.slide_show_type_presenter)
301 elif override_position:
302 ppt_settings.show_type.set(appscript.k.slide_show_type_window)
303 else:
304 ppt_settings.show_type.set(appscript.k.slide_show_type_kiosk)
305 #ppt_settings.show_type.set(appscript.k.slide_show_type_speaker)
306 ppt_window = ppt_settings.run_slide_show()
307 #TODO set slideshow state = running
308# if ppt_window.slideshow_view.slide_state() != appscript.k.slide_show_state_running:
309# ppt_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_running)
310 if not ppt_window or show_presenter_view:
311 return
312 if override_position:
313 top = float(rect.y())
314 height = float(rect.height())
315 left_position = float(rect.x())
316 width = float(rect.width())
317 ppt_window.top.set(top)
318 ppt_window.height.set(height)
319 ppt_window.left_position.set(left_position)
320 ppt_window.width.set(width)
321 else:
322 #TODO set output monitor for fullscreen mode
323 pass
324
325 def get_slide_number(self):
326 """
327 Returns the current slide number.
328 """
329 log.debug(u'get_slide_number')
330 return self.presentation.slide_show_window.slideshow_view.current_show_position()
331
332 def get_slide_count(self):
333 """
334 Returns total number of slides.
335 """
336 log.debug(u'get_slide_count')
337 return len(self.presentation.slides())
338
339 def goto_slide(self, slideno):
340 """
341 Moves to a specific slide in the presentation.
342 """
343 log.debug(u'goto_slide')
344 #TODO this works. but needs to fix this dumb code
345 while self.get_slide_number() != slideno:
346 if self.get_slide_number() < slideno:
347 self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
348 else:
349 self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
350 self.controller.process.activate()
351
352 def next_step(self):
353 """
354 Triggers the next effect of slide on the running presentation.
355 """
356 log.debug(u'next_step')
357 self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
358 self.controller.process.activate()
359 if self.get_slide_number() > self.get_slide_count():
360 self.previous_step()
361
362 def previous_step(self):
363 """
364 Triggers the previous slide on the running presentation.
365 """
366 log.debug(u'previous_step')
367 self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
368 self.controller.process.activate()
369
370 def get_slide_text(self, slide_no):
371 """
372 Returns the text on the slide.
373
374 ``slide_no``
375 The slide the text is required for, starting at 1.
376 """
377 return _get_text_from_shapes(self.presentation.slides[slide_no-1].shapes)
378
379 def get_slide_notes(self, slide_no):
380 """
381 Returns the text on the slide.
382
383 ``slide_no``
384 The slide the notes are required for, starting at 1.
385 """
386 return _get_text_from_shapes(
387 self.presentation.slides[slide_no].notes_page.shapes())
388
389def _get_text_from_shapes(shapes):
390 """
391 Returns any text extracted from the shapes on a presentation slide.
392
393 ``shapes``
394 A set of shapes to search for text.
395 """
396 text = u''
397 for idx in range(len(shapes)):
398 shape = shapes[idx + 1]
399 if shape.has_text_frame():
400 text += shape.text_frame.text_range.content() + '\n'
401 return text
0402
=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
--- openlp/plugins/presentations/lib/presentationtab.py 2013-03-16 21:18:05 +0000
+++ openlp/plugins/presentations/lib/presentationtab.py 2013-04-01 23:08:22 +0000
@@ -30,6 +30,7 @@
30from PyQt4 import QtGui30from PyQt4 import QtGui
3131
32from openlp.core.lib import Settings, SettingsTab, UiStrings, translate32from openlp.core.lib import Settings, SettingsTab, UiStrings, translate
33import sys
3334
3435
35class PresentationTab(SettingsTab):36class PresentationTab(SettingsTab):
@@ -60,6 +61,7 @@
60 controller = self.controllers[key]61 controller = self.controllers[key]
61 checkbox = QtGui.QCheckBox(self.controllers_group_box)62 checkbox = QtGui.QCheckBox(self.controllers_group_box)
62 checkbox.setObjectName(controller.name + u'CheckBox')63 checkbox.setObjectName(controller.name + u'CheckBox')
64<<<<<<< TREE
63 self.presenter_check_boxes[controller.name] = checkbox65 self.presenter_check_boxes[controller.name] = checkbox
64 self.controllers_layout.addWidget(checkbox)66 self.controllers_layout.addWidget(checkbox)
65 self.left_layout.addWidget(self.controllers_group_box)67 self.left_layout.addWidget(self.controllers_group_box)
@@ -73,6 +75,26 @@
73 self.left_layout.addWidget(self.advanced_group_box)75 self.left_layout.addWidget(self.advanced_group_box)
74 self.left_layout.addStretch()76 self.left_layout.addStretch()
75 self.right_layout.addStretch()77 self.right_layout.addStretch()
78=======
79 self.PresenterCheckboxes[controller.name] = checkbox
80 self.ControllersLayout.addWidget(checkbox)
81 self.leftLayout.addWidget(self.ControllersGroupBox)
82 self.AdvancedGroupBox = QtGui.QGroupBox(self.leftColumn)
83 self.AdvancedGroupBox.setObjectName(u'AdvancedGroupBox')
84 self.AdvancedLayout = QtGui.QVBoxLayout(self.AdvancedGroupBox)
85 self.AdvancedLayout.setObjectName(u'AdvancedLayout')
86 self.OverrideAppCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox)
87 self.OverrideAppCheckBox.setObjectName(u'OverrideAppCheckBox')
88 self.AdvancedLayout.addWidget(self.OverrideAppCheckBox)
89 self.ShowPresenterViewCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox)
90 self.ShowPresenterViewCheckBox.setObjectName(u'ShowPresenterViewCheckBox')
91 self.AdvancedLayout.addWidget(self.ShowPresenterViewCheckBox)
92 if not sys.platform.startswith('darwin'):
93 self.ShowPresenterViewCheckBox.setVisible(False)
94 self.leftLayout.addWidget(self.AdvancedGroupBox)
95 self.leftLayout.addStretch()
96 self.rightLayout.addStretch()
97>>>>>>> MERGE-SOURCE
7698
77 def retranslateUi(self):99 def retranslateUi(self):
78 """100 """
@@ -86,6 +108,8 @@
86 self.advanced_group_box.setTitle(UiStrings().Advanced)108 self.advanced_group_box.setTitle(UiStrings().Advanced)
87 self.override_app_check_box.setText(109 self.override_app_check_box.setText(
88 translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))110 translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
111 self.ShowPresenterViewCheckBox.setText(
112 translate('PresentationPlugin.PresentationTab', 'Show Presenter View'))
89113
90 def set_controller_text(self, checkbox, controller):114 def set_controller_text(self, checkbox, controller):
91 if checkbox.isEnabled():115 if checkbox.isEnabled():
@@ -100,9 +124,16 @@
100 """124 """
101 for key in self.controllers:125 for key in self.controllers:
102 controller = self.controllers[key]126 controller = self.controllers[key]
127<<<<<<< TREE
103 checkbox = self.presenter_check_boxes[controller.name]128 checkbox = self.presenter_check_boxes[controller.name]
104 checkbox.setChecked(Settings().value(self.settings_section + u'/' + controller.name))129 checkbox.setChecked(Settings().value(self.settings_section + u'/' + controller.name))
105 self.override_app_check_box.setChecked(Settings().value(self.settings_section + u'/override app'))130 self.override_app_check_box.setChecked(Settings().value(self.settings_section + u'/override app'))
131=======
132 checkbox = self.PresenterCheckboxes[controller.name]
133 checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name))
134 self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app'))
135 self.ShowPresenterViewCheckBox.setChecked(Settings().value(self.settingsSection + u'/show presenter view'))
136>>>>>>> MERGE-SOURCE
106137
107 def save(self):138 def save(self):
108 """139 """
@@ -128,6 +159,10 @@
128 if Settings().value(setting_key) != self.override_app_check_box.checkState():159 if Settings().value(setting_key) != self.override_app_check_box.checkState():
129 Settings().setValue(setting_key, self.override_app_check_box.checkState())160 Settings().setValue(setting_key, self.override_app_check_box.checkState())
130 changed = True161 changed = True
162 setting_key = self.settingsSection + u'/show presenter view'
163 if Settings().value(setting_key) != self.ShowPresenterViewCheckBox.checkState():
164 Settings().setValue(setting_key, self.ShowPresenterViewCheckBox.isChecked())
165 changed = True
131 if changed:166 if changed:
132 self.settings_form.register_post_process(u'mediaitem_suffix_reset')167 self.settings_form.register_post_process(u'mediaitem_suffix_reset')
133 self.settings_form.register_post_process(u'mediaitem_presentation_rebuild')168 self.settings_form.register_post_process(u'mediaitem_presentation_rebuild')
134169
=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py 2013-03-19 19:43:22 +0000
+++ openlp/plugins/presentations/presentationplugin.py 2013-04-01 23:08:22 +0000
@@ -31,6 +31,7 @@
31presentations from a variety of document formats.31presentations from a variety of document formats.
32"""32"""
33import os33import os
34import sys
34import logging35import logging
3536
36from PyQt4 import QtCore37from PyQt4 import QtCore
@@ -46,6 +47,11 @@
46 u'presentations/Impress': QtCore.Qt.Checked,47 u'presentations/Impress': QtCore.Qt.Checked,
47 u'presentations/Powerpoint': QtCore.Qt.Checked,48 u'presentations/Powerpoint': QtCore.Qt.Checked,
48 u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,49 u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
50 u'presentations/Keynote': QtCore.Qt.Checked,
51 u'presentations/show presenter view': QtCore.Qt.Checked,
52 u'PresentationModeUseSecondary': u'',
53 u'PresentationModeEnableFeedbackDisplay': False,
54 u'PresentationModePlayWellWithOthers': False,
49 u'presentations/presentations files': []55 u'presentations/presentations files': []
50 }56 }
5157
@@ -130,6 +136,12 @@
130 u'presentations', u'lib')136 u'presentations', u'lib')
131 for filename in os.listdir(controller_dir):137 for filename in os.listdir(controller_dir):
132 if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':138 if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':
139 if not sys.platform.startswith('darwin') and filename == 'powerpointmaccontroller.py':
140 continue
141 if not sys.platform.startswith('darwin') and filename == 'keynotemaccontroller.py':
142 continue
143 if not sys.platform.startswith('win') and filename == 'powerpointcontroller.py':
144 continue
133 path = os.path.join(controller_dir, filename)145 path = os.path.join(controller_dir, filename)
134 if os.path.isfile(path):146 if os.path.isfile(path):
135 module_name = u'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]147 module_name = u'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]
136148
=== modified file 'scripts/check_dependencies.py'
--- scripts/check_dependencies.py 2013-03-14 10:51:49 +0000
+++ scripts/check_dependencies.py 2013-04-01 23:08:22 +0000
@@ -47,6 +47,7 @@
47 pass47 pass
4848
49IS_WIN = sys.platform.startswith('win')49IS_WIN = sys.platform.startswith('win')
50IS_OSX = sys.platform.startswith('darwin')
5051
51VERS = {52VERS = {
52 'Python': '2.6',53 'Python': '2.6',
@@ -64,6 +65,11 @@
64 'pywintypes',65 'pywintypes',
65]66]
6667
68# OSX
69OSX_MODULES = [
70 'appscript',
71 'mactypes',
72]
67MODULES = [73MODULES = [
68 'PyQt4',74 'PyQt4',
69 'PyQt4.QtCore',75 'PyQt4.QtCore',
@@ -187,6 +193,11 @@
187 print('Checking for Windows specific modules...')193 print('Checking for Windows specific modules...')
188 for m in WIN32_MODULES:194 for m in WIN32_MODULES:
189 check_module(m)195 check_module(m)
196
197 if IS_OSX:
198 print('Checking for OS X specific modules...')
199 for m in OSX_MODULES:
200 check_module(m)
190201
191 verify_versions()202 verify_versions()
192 verify_pyqt()203 verify_pyqt()