Merge lp:~marmyshev/openlp/presentation into lp:openlp
- presentation
- Merge into trunk
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 | ||||
Related bugs: |
|
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.
Commit message
Description of the change
Add support to load presentations with PowerPoint and Keynote on Mac OS X.
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal | # |
Will need to be approved by matysek_
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/
Thanks
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/
self.
File "/Users/
self.
File "/Users/
doc.
File "/Users/
self.
File "/Users/
for filename in os.listdir(
OSError: [Errno 2] No such file or directory: '/Users/
--- System information ---
Platform: Darwin-
--- 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: -
matysek (mzibricky) : Posted in a previous version of this proposal | # |
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 :)
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/
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/
> please reload."
> --
> https:/
> You are the owner of lp:~marmyshev/openlp/presentation.
>
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?
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:/
> You are the owner of lp:~marmyshev/openlp/presentation.
>
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Any progress on this?
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
- You have a conflict in 'openlp/
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, ...).
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. :)
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.
61 +
62 +class KeynoteControll
Before and after the "log = " should be two blank lines
106 + if self.process and len(self.
When dealing with lists do "if not my_list" instead of "if len(my_list) > 0"
387 + text = ''
391 + text += shape.TextFrame
If not explicit wanted do not use strings; use unicode strings: u''
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.
2013-03-23 13:22:37,140 openlp.
2013-03-23 13:22:37,141 openlp.
2013-03-23 13:22:37,141 openlp.
2013-03-23 13:22:37,142 openlp.
2013-03-23 13:22:37,145 openlp.
2013-03-23 13:22:37,146 presentationplugin WARNING Failed to start controller process
2013-03-23 13:22:37,146 openlp.
2013-03-23 13:22:37,146 presentationplugin WARNING Failed to start controller process
2013-03-23 13:22:37,148 openlp.
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.
463 + def check_available
464 + """
465 + PowerPoint is able to run on this machine
466 + """
467 + log.debug(
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.
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.'
- 2122. By Dmitriy Marmyshev
-
returned back appscript import.
Dmitriy Marmyshev (marmyshev) wrote : | # |
I returned back the import. Probably it's temperary.
Please, try all other behaviors of controllers.
- 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
1 | === modified file 'openlp/core/lib/pluginmanager.py' |
2 | --- openlp/core/lib/pluginmanager.py 2013-03-19 19:43:22 +0000 |
3 | +++ openlp/core/lib/pluginmanager.py 2013-04-01 23:08:22 +0000 |
4 | @@ -94,11 +94,6 @@ |
5 | present_plugin_dir = os.path.join(self.base_path, 'presentations') |
6 | log.debug(u'finding plugins in %s at depth %d', unicode(self.base_path), start_depth) |
7 | for root, dirs, files in os.walk(self.base_path): |
8 | - if sys.platform == 'darwin' and root.startswith(present_plugin_dir): |
9 | - # TODO Presentation plugin is not yet working on Mac OS X. |
10 | - # For now just ignore it. The following code will ignore files from the presentation plugin directory |
11 | - # and thereby never import the plugin. |
12 | - continue |
13 | for name in files: |
14 | if name.endswith(u'.py') and not name.startswith(u'__'): |
15 | path = os.path.abspath(os.path.join(root, name)) |
16 | |
17 | === added file 'openlp/plugins/presentations/lib/keynotemaccontroller.py' |
18 | --- openlp/plugins/presentations/lib/keynotemaccontroller.py 1970-01-01 00:00:00 +0000 |
19 | +++ openlp/plugins/presentations/lib/keynotemaccontroller.py 2013-04-01 23:08:22 +0000 |
20 | @@ -0,0 +1,362 @@ |
21 | +# -*- coding: utf-8 -*- |
22 | +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 |
23 | + |
24 | +############################################################################### |
25 | +# OpenLP - Open Source Lyrics Projection # |
26 | +# --------------------------------------------------------------------------- # |
27 | +# Copyright (c) 2008-2012 Raoul Snyman # |
28 | +# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan # |
29 | +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # |
30 | +# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, # |
31 | +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # |
32 | +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # |
33 | +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # |
34 | +# Frode Woldsund, Martin Zibricky # |
35 | +# --------------------------------------------------------------------------- # |
36 | +# This program is free software; you can redistribute it and/or modify it # |
37 | +# under the terms of the GNU General Public License as published by the Free # |
38 | +# Software Foundation; version 2 of the License. # |
39 | +# # |
40 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
41 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
42 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
43 | +# more details. # |
44 | +# # |
45 | +# You should have received a copy of the GNU General Public License along # |
46 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
47 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
48 | +############################################################################### |
49 | + |
50 | +import os |
51 | +import sys |
52 | +import logging |
53 | +import mactypes |
54 | + |
55 | +import appscript |
56 | + |
57 | +from openlp.core.lib import Settings, ScreenList |
58 | +from presentationcontroller import PresentationController, PresentationDocument |
59 | + |
60 | + |
61 | +log = logging.getLogger(__name__) |
62 | + |
63 | + |
64 | +class KeynoteController(PresentationController): |
65 | + """ |
66 | + Class to control interactions with KeyNote Presentations |
67 | + It creates the runtime Environment , Loads the and Closes the Presentation |
68 | + As well as triggering the correct activities based on the users input |
69 | + """ |
70 | + log.info(u'KeynoteController loaded') |
71 | + |
72 | + def __init__(self, plugin): |
73 | + """ |
74 | + Initialise the class |
75 | + """ |
76 | + log.debug(u'Initialising') |
77 | + PresentationController.__init__(self, plugin, u'Keynote', KeynoteDocument) |
78 | + self.supports = [u'key'] |
79 | + self.process = None |
80 | + |
81 | + def check_available(self): |
82 | + """ |
83 | + KeyNote is able to run on this machine |
84 | + """ |
85 | + log.debug(u'check_available') |
86 | + try: |
87 | + self.process = appscript.app('Keynote') |
88 | + except appscript.ApplicationNotFoundError: |
89 | + return False |
90 | + self.kill() |
91 | + return True |
92 | + |
93 | + def start_process(self): |
94 | + """ |
95 | + Loads KeyNote process |
96 | + """ |
97 | + log.debug(u'start_process') |
98 | + if not self.process or not self.process.isrunning(): |
99 | + self.process = appscript.app('Keynote') |
100 | + self.process.relaunchmode = 'limited' #'always' |
101 | + self.process.launch() |
102 | + self.apply_app_settings() |
103 | + |
104 | + def kill(self): |
105 | + """ |
106 | + Called at system exit to clean up any running presentations |
107 | + """ |
108 | + log.debug(u'Kill Keynote') |
109 | + while self.docs and self.process.isrunning(): |
110 | + self.docs[0].close_presentation() |
111 | + if self.process is None or not self.process.isrunning(): |
112 | + return |
113 | + try: |
114 | + total = self.process.slideshows() |
115 | + if self.process and total != appscript.k.missing_value and len(total) > 0: |
116 | + return |
117 | + self.process.quit(saving = appscript.k.ask) |
118 | + except appscript.CantLaunchApplicationError: |
119 | + pass |
120 | + self.process = None |
121 | + |
122 | + def apply_app_settings(self): |
123 | + """ |
124 | + Apply settings for Keynote |
125 | + PresentationModeEnableFeedbackDisplay = True if in settings of OpenLP show presenter view = True |
126 | + PresentationModeUseSecondary = 1 if OpenLP monitor for output = Screen 2 |
127 | + """ |
128 | + openlp_settings = Settings(u'openlp.org',u'OpenLP') |
129 | + keynote_settings = Settings(u'apple', u'iWork.Keynote') |
130 | + use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary')) |
131 | + monitor = openlp_settings.value( u'general/monitor') |
132 | + override_position = openlp_settings.value( u'general/override position') |
133 | + if not override_position and use_secondary != monitor: |
134 | + keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor)) |
135 | + elif override_position and use_secondary != 0: |
136 | + keynote_settings.setValue(u'PresentationModeUseSecondary', u'0') |
137 | + show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view') |
138 | + keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay') |
139 | + if show_presenter_view != keynote_feedback_display: |
140 | + keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view) |
141 | + play_well_with_others = keynote_settings.value(u'PresentationModePlayWellWithOthers') |
142 | + if not play_well_with_others: |
143 | + keynote_settings.setValue(u'PresentationModePlayWellWithOthers', True) |
144 | + |
145 | + |
146 | +class KeynoteDocument(PresentationDocument): |
147 | + """ |
148 | + Class which holds information and controls a single presentation |
149 | + """ |
150 | + |
151 | + def __init__(self, controller, presentation): |
152 | + """ |
153 | + Constructor, store information about the file and initialise |
154 | + """ |
155 | + log.debug(u'Init Presentation Keynote') |
156 | + PresentationDocument.__init__(self, controller, presentation) |
157 | + self.presentation = None |
158 | + |
159 | + def load_presentation(self): |
160 | + """ |
161 | + Called when a presentation is added to the SlideController. |
162 | + Opens the Keynote file using the process created earlier. |
163 | + """ |
164 | + log.debug(u'load_presentation') |
165 | + if not self.controller.process or not self.controller.process.isrunning(): |
166 | + self.controller.start_process() |
167 | + try: |
168 | + self.controller.process.open(self.filepath) |
169 | + except appscript.CommandError: |
170 | + log.debug(u'Keynote open failed') |
171 | + return False |
172 | + slideshows = self.controller.process.slideshows() |
173 | + for slideshow in slideshows: |
174 | + path = slideshow.path() |
175 | + if self.filepath == path: |
176 | + self.presentation = slideshow |
177 | + self.create_thumbnails() |
178 | + return True |
179 | + self.presentation = None |
180 | + return False |
181 | + |
182 | + def create_thumbnails(self): |
183 | + """ |
184 | + Create the thumbnail images for the current presentation. |
185 | + """ |
186 | + log.debug(u'create_thumbnails') |
187 | + if self.check_thumbnails(): |
188 | + return |
189 | + thumbnail_folder = self.get_thumbnail_folder() |
190 | + if not os.path.exists(thumbnail_folder): |
191 | + os.makedirs(thumbnail_folder) |
192 | + try: |
193 | + self.controller.process.open(self.filepath) |
194 | + except appscript.CommandError: |
195 | + log.debug(u'KeyNote open failed') |
196 | + return |
197 | + temp_dir = self.controller.thumbnail_folder |
198 | + keystroke = os.path.join(temp_dir, u'temp' + self.controller.thumbnail_prefix) |
199 | + self.controller.process.activate() |
200 | + appscript.app(u'System Events').processes[u'Keynote'].menu_bars[1].menu_bar_items[3].menus.menu_items[11].click() |
201 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].tool_bars.buttons[4].click() |
202 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].radio_groups[1].radio_buttons[1].click() |
203 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1].click() |
204 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1]\ |
205 | + .menus.menu_items[2].click() |
206 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[2].click() |
207 | + appscript.app(u'System Events').processes[u'Keynote'].keystroke(keystroke) |
208 | + appscript.app(u'System Events').processes[u'Keynote'].key_code(36) |
209 | + appscript.app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[1].click() |
210 | + self.controller.plugin._main_window.activateWindow() |
211 | + slide_no = 0 |
212 | + for filename in os.listdir(temp_dir): |
213 | + full_filename = os.path.join(temp_dir, filename) |
214 | + if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png': |
215 | + continue |
216 | + slide_no = slide_no + 1 |
217 | + if not filename.startswith(self.controller.thumbnail_prefix): |
218 | + path = os.path.join(thumbnail_folder, |
219 | + self.controller.thumbnail_prefix + unicode(slide_no) + u'.png') |
220 | + try: |
221 | + os.rename(full_filename, path) |
222 | + except: |
223 | + open(path,'w').write(open(full_filename,'r').read()) |
224 | + os.unlink(full_filename) |
225 | + |
226 | + def close_presentation(self): |
227 | + """ |
228 | + Close presentation and clean up objects. This is triggered by a new |
229 | + object being added to SlideController or OpenLP being shut down. |
230 | + """ |
231 | + log.debug(u'ClosePresentation') |
232 | + if self.presentation: |
233 | + try: |
234 | + self.presentation.close() |
235 | + except appscript.CommandError: |
236 | + pass |
237 | + self.presentation = None |
238 | + self.controller.remove_doc(self) |
239 | + |
240 | + def is_loaded(self): |
241 | + """ |
242 | + Returns ``True`` if a presentation is loaded. |
243 | + """ |
244 | + log.debug(u'is_loaded') |
245 | + try: |
246 | + if not self.controller.process.isrunning(): |
247 | + return False |
248 | + windows = self.controller.process.windows() |
249 | + if len(windows) == 0: |
250 | + return False |
251 | + slideshows = self.controller.process.slideshows() |
252 | + if len(slideshows) == 0: |
253 | + return False |
254 | + except: |
255 | + return False |
256 | + for slideshow in slideshows: |
257 | + path = slideshow.path() |
258 | + if self.filepath == path: |
259 | + return True |
260 | + return False |
261 | + |
262 | + def is_active(self): |
263 | + """ |
264 | + Returns ``True`` if a presentation is currently active. |
265 | + """ |
266 | + log.debug(u'is_active') |
267 | + if not self.is_loaded(): |
268 | + return False |
269 | + try: |
270 | + if not self.presentation.playing(): |
271 | + return False |
272 | + except appscript.CommandError: |
273 | + return False |
274 | + return True |
275 | + |
276 | + def unblank_screen(self): |
277 | + """ |
278 | + Unblanks (restores) the presentation. |
279 | + """ |
280 | + log.debug(u'unblank_screen') |
281 | + if self.is_blank(): |
282 | + slef.presentation.start_presentation() |
283 | + |
284 | + def blank_screen(self): |
285 | + """ |
286 | + Blanks the screen. |
287 | + """ |
288 | + log.debug(u'blank_screen') |
289 | + self.presentation.stop_slideshow() |
290 | + |
291 | + def is_blank(self): |
292 | + """ |
293 | + Returns ``True`` if screen is blank. |
294 | + """ |
295 | + log.debug(u'is_blank') |
296 | + if self.is_active(): |
297 | + return not self.presentation.playing() |
298 | + else: |
299 | + return False |
300 | + |
301 | + def stop_presentation(self): |
302 | + """ |
303 | + Stops the current presentation and hides the output. |
304 | + """ |
305 | + log.debug(u'stop_presentation') |
306 | + self.presentation.stop_slideshow() |
307 | + |
308 | + |
309 | + def start_presentation(self): |
310 | + """ |
311 | + Starts a presentation from the beginning. |
312 | + """ |
313 | + log.debug(u'start_presentation') |
314 | + if not self.is_active(): |
315 | + self.controller.apply_app_settings() |
316 | + try: |
317 | + self.presentation.start() |
318 | + except appscript.CommandError: |
319 | + return |
320 | + rect = ScreenList().current[u'size'] |
321 | + top = rect.y() |
322 | + height = rect.height() |
323 | + left_position = rect.x() |
324 | + width = rect.width() |
325 | + self.controller.process.windows[1].bounds.set([left_position, top, left_position + width, top + height]) |
326 | + |
327 | + def get_slide_number(self): |
328 | + """ |
329 | + Returns the current slide number. |
330 | + """ |
331 | + log.debug(u'get_slide_number') |
332 | + return self.presentation.current_slide().slide_number() |
333 | + |
334 | + def get_slide_count(self): |
335 | + """ |
336 | + Returns total number of slides. |
337 | + """ |
338 | + log.debug(u'get_slide_count') |
339 | + slides = self.presentation.slides() |
340 | + return len(slides) |
341 | + |
342 | + def goto_slide(self, slideno): |
343 | + """ |
344 | + Moves to a specific slide in the presentation. |
345 | + """ |
346 | + log.debug(u'goto_slide') |
347 | + slide = self.presentation.slides()[slideno-1] |
348 | + self.presentation.show(slide) |
349 | + |
350 | + def next_step(self): |
351 | + """ |
352 | + Triggers the next effect of slide on the running presentation. |
353 | + """ |
354 | + log.debug(u'next_step') |
355 | + self.presentation.show_next() |
356 | + if self.get_slide_number() > self.get_slide_count(): |
357 | + self.previous_step() |
358 | + |
359 | + def previous_step(self): |
360 | + """ |
361 | + Triggers the previous slide on the running presentation. |
362 | + """ |
363 | + log.debug(u'previous_step') |
364 | + self.presentation.show_previous() |
365 | + |
366 | + def get_slide_text(self, slide_no): |
367 | + """ |
368 | + Returns the text on the slide. |
369 | + |
370 | + ``slide_no`` |
371 | + The slide the text is required for, starting at 1. |
372 | + """ |
373 | + return self.presentation.slides[slide_no].body |
374 | + |
375 | + def get_slide_notes(self, slide_no): |
376 | + """ |
377 | + Returns the text on the slide. |
378 | + |
379 | + ``slide_no`` |
380 | + The slide the notes are required for, starting at 1. |
381 | + """ |
382 | + return self.presentation.slides[slide_no].notes |
383 | |
384 | === added file 'openlp/plugins/presentations/lib/powerpointmaccontroller.py' |
385 | --- openlp/plugins/presentations/lib/powerpointmaccontroller.py 1970-01-01 00:00:00 +0000 |
386 | +++ openlp/plugins/presentations/lib/powerpointmaccontroller.py 2013-04-01 23:08:22 +0000 |
387 | @@ -0,0 +1,401 @@ |
388 | +# -*- coding: utf-8 -*- |
389 | +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 |
390 | + |
391 | +############################################################################### |
392 | +# OpenLP - Open Source Lyrics Projection # |
393 | +# --------------------------------------------------------------------------- # |
394 | +# Copyright (c) 2008-2012 Raoul Snyman # |
395 | +# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan # |
396 | +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # |
397 | +# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, # |
398 | +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # |
399 | +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # |
400 | +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # |
401 | +# Frode Woldsund, Martin Zibricky # |
402 | +# --------------------------------------------------------------------------- # |
403 | +# This program is free software; you can redistribute it and/or modify it # |
404 | +# under the terms of the GNU General Public License as published by the Free # |
405 | +# Software Foundation; version 2 of the License. # |
406 | +# # |
407 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
408 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
409 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
410 | +# more details. # |
411 | +# # |
412 | +# You should have received a copy of the GNU General Public License along # |
413 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
414 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
415 | +############################################################################### |
416 | + |
417 | +import os |
418 | +import sys |
419 | +import logging |
420 | +import shutil |
421 | +import mactypes |
422 | + |
423 | +import appscript |
424 | + |
425 | +from openlp.core.lib import Settings, ScreenList |
426 | +from presentationcontroller import PresentationController, PresentationDocument |
427 | + |
428 | + |
429 | +log = logging.getLogger(__name__) |
430 | + |
431 | + |
432 | +class PowerpointController(PresentationController): |
433 | + """ |
434 | + Class to control interactions with PowerPoint Presentations |
435 | + It creates the runtime Environment , Loads the and Closes the Presentation |
436 | + As well as triggering the correct activities based on the users input |
437 | + """ |
438 | + log.info(u'PowerpointController loaded') |
439 | + |
440 | + def __init__(self, plugin): |
441 | + """ |
442 | + Initialise the class |
443 | + """ |
444 | + log.debug(u'Initialising') |
445 | + PresentationController.__init__(self, plugin, u'Powerpoint', PowerpointDocument) |
446 | + self.supports = [u'ppt', u'pps', u'pptx', u'ppsx'] |
447 | + self.process = None |
448 | + |
449 | + def check_available(self): |
450 | + """ |
451 | + PowerPoint is able to run on this machine |
452 | + """ |
453 | + log.debug(u'check_available') |
454 | + try: |
455 | + self.process = appscript.app(id='com.microsoft.powerpoint') |
456 | + except appscript.ApplicationNotFoundError: |
457 | + return False |
458 | + self.kill() |
459 | + return True |
460 | + |
461 | + def start_process(self): |
462 | + """ |
463 | + Loads PowerPoint process |
464 | + """ |
465 | + log.debug(u'start_process') |
466 | + if not self.process or not self.process.isrunning(): |
467 | + self.process = appscript.app(id='com.microsoft.powerpoint') |
468 | + self.process.relaunchmode = 'limited' #'always' |
469 | + self.process.launch() |
470 | + self.apply_app_settings() |
471 | + |
472 | + def kill(self): |
473 | + """ |
474 | + Called at system exit to clean up any running presentations |
475 | + """ |
476 | + log.debug(u'Kill Powerpoint') |
477 | + while self.docs and self.process.isrunning(): |
478 | + self.docs[0].close_presentation() |
479 | + if self.process is None or not self.process.isrunning(): |
480 | + return |
481 | + try: |
482 | + total = self.process.presentations() |
483 | + if self.process and total != appscript.k.missing_value and len(total) > 0: |
484 | + return |
485 | + self.process.quit(saving = appscript.k.ask) |
486 | + except appscript.CantLaunchApplicationError: |
487 | + pass |
488 | + self.process = None |
489 | + |
490 | + def apply_app_settings(self): |
491 | + """ |
492 | + Apply settings for PowerPoint |
493 | + 14\Options\Options\Save graphics screen heigth = 240 |
494 | + 14\Options\Options\Save graphics screen width = 320 |
495 | + 14\Options\Options\Save only current slide graphics = 0 |
496 | + |
497 | + """ |
498 | + openlp_settings = Settings("openlp.org","OpenLP") |
499 | + ppt_settings = Settings("Microsoft", "Powerpoint") |
500 | +# use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary', u'')) |
501 | +# monitor = openlp_settings.value( u'general/monitor', 0) |
502 | +# display_on_monitor = openlp_settings.value( u'general/display on monitor', False) |
503 | +# if display_on_monitor and use_secondary != monitor: |
504 | +# keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor)) |
505 | +# elif not display_on_monitor and use_secondary > 0: |
506 | +# keynote_settings.setValue(u'PresentationModeUseSecondary', u'0') |
507 | +# show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view', False) |
508 | +# keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay', False) |
509 | +# if show_presenter_view != keynote_feedback_display: |
510 | +# keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view) |
511 | + |
512 | + |
513 | +class PowerpointDocument(PresentationDocument): |
514 | + """ |
515 | + Class which holds information and controls a single presentation |
516 | + """ |
517 | + |
518 | + def __init__(self, controller, presentation): |
519 | + """ |
520 | + Constructor, store information about the file and initialise |
521 | + """ |
522 | + log.debug(u'Init Presentation Powerpoint') |
523 | + PresentationDocument.__init__(self, controller, presentation) |
524 | + self.presentation = None |
525 | + |
526 | + def load_presentation(self): |
527 | + """ |
528 | + Called when a presentation is added to the SlideController. |
529 | + Opens the PowerPoint file using the process created earlier. |
530 | + """ |
531 | + log.debug(u'load_presentation') |
532 | + if not self.controller.process or not self.controller.process.isrunning(): |
533 | + self.controller.start_process() |
534 | + try: |
535 | + self.controller.process.open(self.filepath) |
536 | + except appscript.CommandError: |
537 | + log.debug(u'PPT open failed') |
538 | + return False |
539 | + presentations = self.controller.process.presentations() |
540 | + for presentation in presentations: |
541 | + full_name = presentation.full_name() |
542 | + full_name = full_name.replace(u'Macintosh HD', u'') |
543 | + full_name = full_name.replace(u':', u'/') |
544 | + if self.filepath == full_name: |
545 | + self.presentation = presentation |
546 | + self.create_thumbnails() |
547 | + return True |
548 | + return False |
549 | + |
550 | + def create_thumbnails(self): |
551 | + """ |
552 | + Create the thumbnail images for the current presentation. |
553 | + """ |
554 | + log.debug(u'create_thumbnails') |
555 | + if self.check_thumbnails(): |
556 | + return |
557 | + thumbnail_folder = self.get_thumbnail_folder() |
558 | + self.presentation.save(in_ = thumbnail_folder, as_ = appscript.k.save_as_PNG) |
559 | + slide_no = 0 |
560 | + temp_dir = os.path.join(thumbnail_folder, self.get_file_name()) |
561 | + if not os.path.isdir(temp_dir): |
562 | +# log.debug(u'create_thumbnails failed') |
563 | + temp_dir = thumbnail_folder |
564 | + for filename in os.listdir(temp_dir): |
565 | + full_filename = os.path.join(temp_dir, filename) |
566 | + if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png': |
567 | + continue |
568 | + slide_no = slide_no + 1 |
569 | + if not filename.startswith(self.controller.thumbnail_prefix): |
570 | + path = os.path.join(thumbnail_folder, |
571 | + self.controller.thumbnail_prefix + unicode(slide_no) + u'.png') |
572 | + try: |
573 | + os.rename(full_filename, path) |
574 | + except: |
575 | + open(path,'w').write(open(full_filename,'r').read()) |
576 | + os.unlink(full_filename) |
577 | + if temp_dir != thumbnail_folder: |
578 | + try: |
579 | + shutil.rmtree(temp_dir) |
580 | + except: |
581 | + pass |
582 | + |
583 | + def close_presentation(self): |
584 | + """ |
585 | + Close presentation and clean up objects. This is triggered by a new |
586 | + object being added to SlideController or OpenLP being shut down. |
587 | + """ |
588 | + log.debug(u'ClosePresentation') |
589 | + if self.presentation: |
590 | + try: |
591 | + self.presentation.close() |
592 | + except appscript.CommandError: |
593 | + pass |
594 | + self.presentation = None |
595 | + self.controller.remove_doc(self) |
596 | + |
597 | + def is_loaded(self): |
598 | + """ |
599 | + Returns ``True`` if a presentation is loaded. |
600 | + """ |
601 | + log.debug(u'is_loaded') |
602 | + try: |
603 | + if not self.controller.process.isrunning(): |
604 | + return False |
605 | + if len(self.controller.process.document_windows()) == 0: |
606 | + return False |
607 | + presentations = self.controller.process.presentations() |
608 | + if len(presentations) == 0: |
609 | + return False |
610 | + except: |
611 | + return False |
612 | + for presentation in presentations: |
613 | + full_name = presentation.full_name() |
614 | + full_name = full_name.replace(u'Macintosh HD', u'') |
615 | + full_name = full_name.replace(u':', u'/') |
616 | + if self.filepath == full_name: |
617 | + return True |
618 | + return False |
619 | + |
620 | + def is_active(self): |
621 | + """ |
622 | + Returns ``True`` if a presentation is currently active. |
623 | + """ |
624 | + log.debug(u'is_active') |
625 | + if not self.is_loaded(): |
626 | + return False |
627 | + try: |
628 | + slide_show_window = self.presentation.slide_show_window |
629 | + if slide_show_window is None: |
630 | + return False |
631 | + slide_state = self.presentation.slide_show_window.slideshow_view.slide_state() |
632 | + if slide_state is None or slide_state == appscript.k.missing_value: |
633 | + return False |
634 | + except: |
635 | + return False |
636 | + return True |
637 | + |
638 | + def unblank_screen(self): |
639 | + """ |
640 | + Unblanks (restores) the presentation. |
641 | + """ |
642 | + log.debug(u'unblank_screen') |
643 | + if self.is_blank(): |
644 | + settings = self.presentation.slide_show_settings |
645 | + #settings.run_slide_show() |
646 | + self.presentation.slide_show_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_running) |
647 | + self.presentation.slide_show_window.slideshow_view.go_to_next_slide() |
648 | + self.presentation.slide_show_window.slideshow_view.go_to_previous_slide() |
649 | + |
650 | + def blank_screen(self): |
651 | + """ |
652 | + Blanks the screen. |
653 | + """ |
654 | + log.debug(u'blank_screen') |
655 | + self.presentation.slide_show_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_black_screen) |
656 | + |
657 | + def is_blank(self): |
658 | + """ |
659 | + Returns ``True`` if screen is blank. |
660 | + """ |
661 | + log.debug(u'is_blank') |
662 | + if self.is_active() and self.presentation.slide_show_window.slideshow_view\ |
663 | + .slide_state() is appscript.k.slide_show_state_black_screen: |
664 | + return True |
665 | + else: |
666 | + return False |
667 | + |
668 | + def stop_presentation(self): |
669 | + """ |
670 | + Stops the current presentation and hides the output. |
671 | + """ |
672 | + log.debug(u'stop_presentation') |
673 | + self.presentation.slide_show_window.slideshow_view.exit_slide_show() |
674 | + |
675 | + |
676 | + def start_presentation(self): |
677 | + """ |
678 | + Starts a presentation from the beginning. |
679 | + """ |
680 | + log.debug(u'start_presentation') |
681 | + rect = ScreenList().current[u'size'] |
682 | + ppt_settings = self.presentation.slide_show_settings |
683 | + openlp_settings = Settings("openlp.org","OpenLP") |
684 | + show_presenter_view = openlp_settings.value(self.controller.plugin.settingsSection + u'/show presenter view') |
685 | + override_position = openlp_settings.value( u'general/override position') |
686 | + if show_presenter_view: |
687 | + ppt_settings.show_type.set(appscript.k.slide_show_type_presenter) |
688 | + elif override_position: |
689 | + ppt_settings.show_type.set(appscript.k.slide_show_type_window) |
690 | + else: |
691 | + ppt_settings.show_type.set(appscript.k.slide_show_type_kiosk) |
692 | + #ppt_settings.show_type.set(appscript.k.slide_show_type_speaker) |
693 | + ppt_window = ppt_settings.run_slide_show() |
694 | + #TODO set slideshow state = running |
695 | +# if ppt_window.slideshow_view.slide_state() != appscript.k.slide_show_state_running: |
696 | +# ppt_window.slideshow_view.slide_state.set(appscript.k.slide_show_state_running) |
697 | + if not ppt_window or show_presenter_view: |
698 | + return |
699 | + if override_position: |
700 | + top = float(rect.y()) |
701 | + height = float(rect.height()) |
702 | + left_position = float(rect.x()) |
703 | + width = float(rect.width()) |
704 | + ppt_window.top.set(top) |
705 | + ppt_window.height.set(height) |
706 | + ppt_window.left_position.set(left_position) |
707 | + ppt_window.width.set(width) |
708 | + else: |
709 | + #TODO set output monitor for fullscreen mode |
710 | + pass |
711 | + |
712 | + def get_slide_number(self): |
713 | + """ |
714 | + Returns the current slide number. |
715 | + """ |
716 | + log.debug(u'get_slide_number') |
717 | + return self.presentation.slide_show_window.slideshow_view.current_show_position() |
718 | + |
719 | + def get_slide_count(self): |
720 | + """ |
721 | + Returns total number of slides. |
722 | + """ |
723 | + log.debug(u'get_slide_count') |
724 | + return len(self.presentation.slides()) |
725 | + |
726 | + def goto_slide(self, slideno): |
727 | + """ |
728 | + Moves to a specific slide in the presentation. |
729 | + """ |
730 | + log.debug(u'goto_slide') |
731 | + #TODO this works. but needs to fix this dumb code |
732 | + while self.get_slide_number() != slideno: |
733 | + if self.get_slide_number() < slideno: |
734 | + self.presentation.slide_show_window.slideshow_view.go_to_next_slide() |
735 | + else: |
736 | + self.presentation.slide_show_window.slideshow_view.go_to_previous_slide() |
737 | + self.controller.process.activate() |
738 | + |
739 | + def next_step(self): |
740 | + """ |
741 | + Triggers the next effect of slide on the running presentation. |
742 | + """ |
743 | + log.debug(u'next_step') |
744 | + self.presentation.slide_show_window.slideshow_view.go_to_next_slide() |
745 | + self.controller.process.activate() |
746 | + if self.get_slide_number() > self.get_slide_count(): |
747 | + self.previous_step() |
748 | + |
749 | + def previous_step(self): |
750 | + """ |
751 | + Triggers the previous slide on the running presentation. |
752 | + """ |
753 | + log.debug(u'previous_step') |
754 | + self.presentation.slide_show_window.slideshow_view.go_to_previous_slide() |
755 | + self.controller.process.activate() |
756 | + |
757 | + def get_slide_text(self, slide_no): |
758 | + """ |
759 | + Returns the text on the slide. |
760 | + |
761 | + ``slide_no`` |
762 | + The slide the text is required for, starting at 1. |
763 | + """ |
764 | + return _get_text_from_shapes(self.presentation.slides[slide_no-1].shapes) |
765 | + |
766 | + def get_slide_notes(self, slide_no): |
767 | + """ |
768 | + Returns the text on the slide. |
769 | + |
770 | + ``slide_no`` |
771 | + The slide the notes are required for, starting at 1. |
772 | + """ |
773 | + return _get_text_from_shapes( |
774 | + self.presentation.slides[slide_no].notes_page.shapes()) |
775 | + |
776 | +def _get_text_from_shapes(shapes): |
777 | + """ |
778 | + Returns any text extracted from the shapes on a presentation slide. |
779 | + |
780 | + ``shapes`` |
781 | + A set of shapes to search for text. |
782 | + """ |
783 | + text = u'' |
784 | + for idx in range(len(shapes)): |
785 | + shape = shapes[idx + 1] |
786 | + if shape.has_text_frame(): |
787 | + text += shape.text_frame.text_range.content() + '\n' |
788 | + return text |
789 | |
790 | === modified file 'openlp/plugins/presentations/lib/presentationtab.py' |
791 | --- openlp/plugins/presentations/lib/presentationtab.py 2013-03-16 21:18:05 +0000 |
792 | +++ openlp/plugins/presentations/lib/presentationtab.py 2013-04-01 23:08:22 +0000 |
793 | @@ -30,6 +30,7 @@ |
794 | from PyQt4 import QtGui |
795 | |
796 | from openlp.core.lib import Settings, SettingsTab, UiStrings, translate |
797 | +import sys |
798 | |
799 | |
800 | class PresentationTab(SettingsTab): |
801 | @@ -60,6 +61,7 @@ |
802 | controller = self.controllers[key] |
803 | checkbox = QtGui.QCheckBox(self.controllers_group_box) |
804 | checkbox.setObjectName(controller.name + u'CheckBox') |
805 | +<<<<<<< TREE |
806 | self.presenter_check_boxes[controller.name] = checkbox |
807 | self.controllers_layout.addWidget(checkbox) |
808 | self.left_layout.addWidget(self.controllers_group_box) |
809 | @@ -73,6 +75,26 @@ |
810 | self.left_layout.addWidget(self.advanced_group_box) |
811 | self.left_layout.addStretch() |
812 | self.right_layout.addStretch() |
813 | +======= |
814 | + self.PresenterCheckboxes[controller.name] = checkbox |
815 | + self.ControllersLayout.addWidget(checkbox) |
816 | + self.leftLayout.addWidget(self.ControllersGroupBox) |
817 | + self.AdvancedGroupBox = QtGui.QGroupBox(self.leftColumn) |
818 | + self.AdvancedGroupBox.setObjectName(u'AdvancedGroupBox') |
819 | + self.AdvancedLayout = QtGui.QVBoxLayout(self.AdvancedGroupBox) |
820 | + self.AdvancedLayout.setObjectName(u'AdvancedLayout') |
821 | + self.OverrideAppCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox) |
822 | + self.OverrideAppCheckBox.setObjectName(u'OverrideAppCheckBox') |
823 | + self.AdvancedLayout.addWidget(self.OverrideAppCheckBox) |
824 | + self.ShowPresenterViewCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox) |
825 | + self.ShowPresenterViewCheckBox.setObjectName(u'ShowPresenterViewCheckBox') |
826 | + self.AdvancedLayout.addWidget(self.ShowPresenterViewCheckBox) |
827 | + if not sys.platform.startswith('darwin'): |
828 | + self.ShowPresenterViewCheckBox.setVisible(False) |
829 | + self.leftLayout.addWidget(self.AdvancedGroupBox) |
830 | + self.leftLayout.addStretch() |
831 | + self.rightLayout.addStretch() |
832 | +>>>>>>> MERGE-SOURCE |
833 | |
834 | def retranslateUi(self): |
835 | """ |
836 | @@ -86,6 +108,8 @@ |
837 | self.advanced_group_box.setTitle(UiStrings().Advanced) |
838 | self.override_app_check_box.setText( |
839 | translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden')) |
840 | + self.ShowPresenterViewCheckBox.setText( |
841 | + translate('PresentationPlugin.PresentationTab', 'Show Presenter View')) |
842 | |
843 | def set_controller_text(self, checkbox, controller): |
844 | if checkbox.isEnabled(): |
845 | @@ -100,9 +124,16 @@ |
846 | """ |
847 | for key in self.controllers: |
848 | controller = self.controllers[key] |
849 | +<<<<<<< TREE |
850 | checkbox = self.presenter_check_boxes[controller.name] |
851 | checkbox.setChecked(Settings().value(self.settings_section + u'/' + controller.name)) |
852 | self.override_app_check_box.setChecked(Settings().value(self.settings_section + u'/override app')) |
853 | +======= |
854 | + checkbox = self.PresenterCheckboxes[controller.name] |
855 | + checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name)) |
856 | + self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app')) |
857 | + self.ShowPresenterViewCheckBox.setChecked(Settings().value(self.settingsSection + u'/show presenter view')) |
858 | +>>>>>>> MERGE-SOURCE |
859 | |
860 | def save(self): |
861 | """ |
862 | @@ -128,6 +159,10 @@ |
863 | if Settings().value(setting_key) != self.override_app_check_box.checkState(): |
864 | Settings().setValue(setting_key, self.override_app_check_box.checkState()) |
865 | changed = True |
866 | + setting_key = self.settingsSection + u'/show presenter view' |
867 | + if Settings().value(setting_key) != self.ShowPresenterViewCheckBox.checkState(): |
868 | + Settings().setValue(setting_key, self.ShowPresenterViewCheckBox.isChecked()) |
869 | + changed = True |
870 | if changed: |
871 | self.settings_form.register_post_process(u'mediaitem_suffix_reset') |
872 | self.settings_form.register_post_process(u'mediaitem_presentation_rebuild') |
873 | |
874 | === modified file 'openlp/plugins/presentations/presentationplugin.py' |
875 | --- openlp/plugins/presentations/presentationplugin.py 2013-03-19 19:43:22 +0000 |
876 | +++ openlp/plugins/presentations/presentationplugin.py 2013-04-01 23:08:22 +0000 |
877 | @@ -31,6 +31,7 @@ |
878 | presentations from a variety of document formats. |
879 | """ |
880 | import os |
881 | +import sys |
882 | import logging |
883 | |
884 | from PyQt4 import QtCore |
885 | @@ -46,6 +47,11 @@ |
886 | u'presentations/Impress': QtCore.Qt.Checked, |
887 | u'presentations/Powerpoint': QtCore.Qt.Checked, |
888 | u'presentations/Powerpoint Viewer': QtCore.Qt.Checked, |
889 | + u'presentations/Keynote': QtCore.Qt.Checked, |
890 | + u'presentations/show presenter view': QtCore.Qt.Checked, |
891 | + u'PresentationModeUseSecondary': u'', |
892 | + u'PresentationModeEnableFeedbackDisplay': False, |
893 | + u'PresentationModePlayWellWithOthers': False, |
894 | u'presentations/presentations files': [] |
895 | } |
896 | |
897 | @@ -130,6 +136,12 @@ |
898 | u'presentations', u'lib') |
899 | for filename in os.listdir(controller_dir): |
900 | if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py': |
901 | + if not sys.platform.startswith('darwin') and filename == 'powerpointmaccontroller.py': |
902 | + continue |
903 | + if not sys.platform.startswith('darwin') and filename == 'keynotemaccontroller.py': |
904 | + continue |
905 | + if not sys.platform.startswith('win') and filename == 'powerpointcontroller.py': |
906 | + continue |
907 | path = os.path.join(controller_dir, filename) |
908 | if os.path.isfile(path): |
909 | module_name = u'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0] |
910 | |
911 | === modified file 'scripts/check_dependencies.py' |
912 | --- scripts/check_dependencies.py 2013-03-14 10:51:49 +0000 |
913 | +++ scripts/check_dependencies.py 2013-04-01 23:08:22 +0000 |
914 | @@ -47,6 +47,7 @@ |
915 | pass |
916 | |
917 | IS_WIN = sys.platform.startswith('win') |
918 | +IS_OSX = sys.platform.startswith('darwin') |
919 | |
920 | VERS = { |
921 | 'Python': '2.6', |
922 | @@ -64,6 +65,11 @@ |
923 | 'pywintypes', |
924 | ] |
925 | |
926 | +# OSX |
927 | +OSX_MODULES = [ |
928 | + 'appscript', |
929 | + 'mactypes', |
930 | +] |
931 | MODULES = [ |
932 | 'PyQt4', |
933 | 'PyQt4.QtCore', |
934 | @@ -187,6 +193,11 @@ |
935 | print('Checking for Windows specific modules...') |
936 | for m in WIN32_MODULES: |
937 | check_module(m) |
938 | + |
939 | + if IS_OSX: |
940 | + print('Checking for OS X specific modules...') |
941 | + for m in OSX_MODULES: |
942 | + check_module(m) |
943 | |
944 | verify_versions() |
945 | verify_pyqt() |
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