openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #18712
[Merge] lp:~marmyshev/openlp/presentation into lp:openlp
Dmitriy Marmyshev has proposed merging lp:~marmyshev/openlp/presentation into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
Bug #836574 in OpenLP: "PowerPoint Presentations with Office for Mac"
https://bugs.launchpad.net/openlp/+bug/836574
For more details, see:
https://code.launchpad.net/~marmyshev/openlp/presentation/+merge/143389
Add support to load presentations with PowerPoint and Keynote on Mac OS X.
--
https://code.launchpad.net/~marmyshev/openlp/presentation/+merge/143389
Your team OpenLP Core is requested to review the proposed merge of lp:~marmyshev/openlp/presentation into lp:openlp.
=== modified file 'openlp/core/lib/pluginmanager.py'
--- openlp/core/lib/pluginmanager.py 2012-12-29 20:56:56 +0000
+++ openlp/core/lib/pluginmanager.py 2013-01-15 19:35:24 +0000
@@ -92,8 +92,8 @@
if sys.platform == 'darwin':
present_plugin_dir = os.path.join(plugin_dir, 'presentations')
# Ignore files from the presentation plugin directory.
- if root.startswith(present_plugin_dir):
- continue
+ #if root.startswith(present_plugin_dir):
+ #continue
for name in files:
if name.endswith(u'.py') and not name.startswith(u'__'):
path = os.path.abspath(os.path.join(root, name))
=== 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-01-15 19:35:24 +0000
@@ -0,0 +1,383 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2012 Raoul Snyman #
+# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
+# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
+# Frode Woldsund, Martin Zibricky #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+
+import os
+import sys
+import logging
+
+from appscript import *
+
+from openlp.core.lib import Settings
+from presentationcontroller import PresentationController, PresentationDocument
+
+log = logging.getLogger(__name__)
+
+# PPT API documentation:
+# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
+
+class KeynoteController(PresentationController):
+ """
+ Class to control interactions with KeyNote Presentations
+ It creates the runtime Environment , Loads the and Closes the Presentation
+ As well as triggering the correct activities based on the users input
+ """
+ log.info(u'KeynoteController loaded')
+
+ def __init__(self, plugin):
+ """
+ Initialise the class
+ """
+ log.debug(u'Initialising')
+ PresentationController.__init__(self, plugin, u'Keynote', KeynoteDocument)
+ self.supports = [u'key']
+ self.process = None
+
+ def check_available(self):
+ """
+ KeyNote is able to run on this machine
+ """
+ log.debug(u'check_available')
+ return True
+ #return False
+
+
+ def start_process(self):
+ """
+ Loads KeyNote process
+ """
+ log.debug(u'start_process')
+ if not self.process:
+ self.process = app('Keynote')
+ self.process.relaunchmode = 'always'
+ self.apply_app_settings()
+
+ def kill(self):
+ """
+ Called at system exit to clean up any running presentations
+ """
+ log.debug(u'Kill keynote')
+ while self.docs:
+ self.docs[0].close_presentation()
+ if self.process is None:
+ return
+ try:
+ if self.process and len(self.process.slideshows()) > 0:
+ return
+ self.process.quit(saving_ = k.no)
+ #except pywintypes.com_error:
+ except:
+ pass
+ self.process = None
+
+ def apply_app_settings(self):
+ """
+ Apply settings for Keynote
+ PresentationModeEnableFeedbackDisplay = True if in settings of OpenLP show presenter view = True
+ PresentationModeUseSecondary = 1 if OpenLP monitor for output = Screen 2
+ """
+ openlp_settings = Settings("openlp.org","OpenLP")
+ keynote_settings = Settings("apple", "iWork.Keynote")
+ use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary', u''))
+ monitor = openlp_settings.value( u'general/monitor', 0)
+ override_position = openlp_settings.value( u'general/override position', False)
+ if not override_position and use_secondary <> monitor:
+ keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor))
+ elif override_position and use_secondary <> 0:
+ keynote_settings.setValue(u'PresentationModeUseSecondary', u'0')
+ show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view', False)
+ keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay', False)
+ if show_presenter_view <> keynote_feedback_display:
+ keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view)
+ play_well_with_others = keynote_settings.value(u'PresentationModePlayWellWithOthers', False)
+ if not play_well_with_others:
+ keynote_settings.setValue(u'PresentationModePlayWellWithOthers', True)
+
+
+class KeynoteDocument(PresentationDocument):
+ """
+ Class which holds information and controls a single presentation
+ """
+
+ def __init__(self, controller, presentation):
+ """
+ Constructor, store information about the file and initialise
+ """
+ log.debug(u'Init Presentation Keynote')
+ PresentationDocument.__init__(self, controller, presentation)
+ self.presentation = None
+
+ def load_presentation(self):
+ """
+ Called when a presentation is added to the SlideController.
+ Opens the KeyNote file using the process created earlier.
+ """
+ log.debug(u'load_presentation')
+ if not self.controller.process or not self.controller.process.isrunning():
+ self.controller.start_process()
+ try:
+ self.controller.process.open(self.filepath)
+ #except pywintypes.com_error:
+ except:
+ log.debug(u'KeyNote open failed')
+ return False
+ self.presentation = self.controller.process.slideshows[
+ len(self.controller.process.slideshows())-1]
+ self.create_thumbnails()
+ return True
+
+ def create_thumbnails(self):
+ """
+ Create the thumbnail images for the current presentation.
+
+ Note an alternative and quicker method would be do::
+
+ self.presentation.Slides[n].Copy()
+ thumbnail = QApplication.clipboard.image()
+
+ However, for the moment, we want a physical file since it makes life
+ easier elsewhere.
+ """
+ log.debug(u'create_thumbnails')
+ if self.check_thumbnails():
+ return
+ #debug
+ #return
+ get_thumbnail_folder = self.get_thumbnail_folder()
+ if not os.path.exists(get_thumbnail_folder):
+ os.makedirs(get_thumbnail_folder)
+ try:
+ self.controller.process.open(self.filepath)
+ except:
+ log.debug(u'KeyNote open failed')
+ return
+ self.controller.process.activate()
+ app(u'System Events').processes[u'Keynote'].menu_bars[1].menu_bar_items[3].menus.menu_items[11].click()
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].tool_bars.buttons[4].click()
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].radio_groups[1].radio_buttons[1].click()
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1].click()
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].pop_up_buttons[1].menus.menu_items[2].click()
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[2].click()
+ app(u'System Events').processes[u'Keynote'].keystroke(os.path.join(get_thumbnail_folder, u'temp' + self.controller.thumbnail_prefix))
+ #app(u'System Events').processes[u'Keynote'].keystroke(u'\r')
+ app(u'System Events').processes[u'Keynote'].key_code(36)
+ app(u'System Events').processes[u'Keynote'].windows[1].sheets[1].buttons[1].click()
+ #self.activate()
+ slide_no = 0
+# temp_dir = os.path.join(get_thumbnail_folder, self.get_file_name())
+ for filename in os.listdir(get_thumbnail_folder):
+ full_filename = os.path.join(get_thumbnail_folder, filename)
+ if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png':
+ continue
+ slide_no = slide_no + 1
+ if not filename.startswith(self.controller.thumbnail_prefix):
+ path = os.path.join(get_thumbnail_folder,
+ self.controller.thumbnail_prefix + unicode(slide_no) + u'.png')
+ try:
+ os.rename(full_filename, path)
+ except:
+ open(path,'w').write(open(full_filename,'r').read())
+ os.unlink(full_filename)
+# try:
+# shutil.rmtree(temp_dir)
+# except:
+# pass
+
+ def close_presentation(self):
+ """
+ Close presentation and clean up objects. This is triggered by a new
+ object being added to SlideController or OpenLP being shut down.
+ """
+ log.debug(u'ClosePresentation')
+ if self.presentation:
+ try:
+ self.presentation.close()
+ #except pywintypes.com_error:
+ except:
+ pass
+ self.presentation = None
+ self.controller.remove_doc(self)
+
+ def is_loaded(self):
+ """
+ Returns ``True`` if a presentation is loaded.
+ """
+ log.debug(u'is_loaded')
+ try:
+ #TODO this doesnt works right
+ if not self.controller.process.isrunning():
+ return False
+ if len(self.controller.process.windows()) == 0:
+ return False
+ if len(self.controller.process.slideshows()) == 0:
+ return False
+ except:
+ return False
+ return True
+
+ def is_active(self):
+ """
+ Returns ``True`` if a presentation is currently active.
+ """
+ log.debug(u'is_active')
+ if not self.is_loaded():
+ return False
+ try:
+ if not self.presentation.playing():
+ return False
+ except:
+ return False
+ return True
+
+ def unblank_screen(self):
+ """
+ Unblanks (restores) the presentation.
+ """
+ log.debug(u'unblank_screen')
+# settings = self.presentation.slide_show_settings
+# settings.run_slide_show()
+# self.presentation.slide_show_window().slide_show_view().slide_state()\
+# .set(k.slide_show_state_running)
+# self.presentation.SlideShowSettings.Run()
+# self.presentation.SlideShowWindow.View.State = 1
+# self.presentation.SlideShowWindow.Activate()
+
+ def blank_screen(self):
+ """
+ Blanks the screen.
+ """
+ log.debug(u'blank_screen')
+# self.presentation.slide_show_window().slide_show_view().slide_state()\
+# .set(k.slide_show_state_black_screen)
+
+ def is_blank(self):
+ """
+ Returns ``True`` if screen is blank.
+ """
+ log.debug(u'is_blank')
+ if self.is_active():
+ return not self.presentation.playing()
+ else:
+ return False
+
+ def stop_presentation(self):
+ """
+ Stops the current presentation and hides the output.
+ """
+ log.debug(u'stop_presentation')
+ self.presentation.stop_slideshow()
+
+
+ def start_presentation(self):
+ """
+ Starts a presentation from the beginning.
+ """
+ log.debug(u'start_presentation')
+ if not self.is_active():
+ self.controller.apply_app_settings()
+ try:
+ self.presentation.start()
+ except:
+ return
+ renderer = self.controller.plugin.renderer
+ rect = renderer.screens.current[u'size']
+ top = rect.y()
+ height = rect.height()
+ left_position = rect.x()
+ width = rect.width()
+ self.controller.process.windows[1].bounds.set([left_position, top, left_position + width, top + height])
+
+ def get_slide_number(self):
+ """
+ Returns the current slide number.
+ """
+ log.debug(u'get_slide_number')
+ return self.presentation.current_slide().slide_number()
+
+ def get_slide_count(self):
+ """
+ Returns total number of slides.
+ """
+ log.debug(u'get_slide_count')
+ return len(self.presentation.slides())
+
+ def goto_slide(self, slideno):
+ """
+ Moves to a specific slide in the presentation.
+ """
+ log.debug(u'goto_slide')
+ slide = self.presentation.slides()[slideno-1]
+ self.presentation.show(slide)
+
+ def next_step(self):
+ """
+ Triggers the next effect of slide on the running presentation.
+ """
+ log.debug(u'next_step')
+ self.presentation.show_next()
+ if self.get_slide_number() > self.get_slide_count():
+ self.previous_step()
+
+ def previous_step(self):
+ """
+ Triggers the previous slide on the running presentation.
+ """
+ log.debug(u'previous_step')
+ self.presentation.show_previous()
+
+ def get_slide_text(self, slide_no):
+ """
+ Returns the text on the slide.
+
+ ``slide_no``
+ The slide the text is required for, starting at 1.
+ """
+ return self.presentation.slides[slide_no].body
+
+ def get_slide_notes(self, slide_no):
+ """
+ Returns the text on the slide.
+
+ ``slide_no``
+ The slide the notes are required for, starting at 1.
+ """
+ return self.presentation.slides[slide_no].notes
+
+def _get_text_from_shapes(shapes):
+ """
+ Returns any text extracted from the shapes on a presentation slide.
+
+ ``shapes``
+ A set of shapes to search for text.
+ """
+ text = ''
+ for idx in range(shapes.Count):
+ shape = shapes(idx + 1)
+ if shape.HasTextFrame:
+ text += shape.TextFrame.TextRange.Text + '\n'
+ return text
=== 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-01-15 19:35:24 +0000
@@ -0,0 +1,402 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2012 Raoul Snyman #
+# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
+# Meinert Jordan, Armin Köhler, Eric Ludin, Edwin Lunando, Brian T. Meyer, #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
+# Frode Woldsund, Martin Zibricky #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+
+import os
+import sys
+import logging
+import shutil
+
+from appscript import *
+
+from openlp.core.lib import Settings
+from presentationcontroller import PresentationController, PresentationDocument
+
+log = logging.getLogger(__name__)
+
+# PPT API documentation:
+# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
+
+class PowerpointController(PresentationController):
+ """
+ Class to control interactions with PowerPoint Presentations
+ It creates the runtime Environment , Loads the and Closes the Presentation
+ As well as triggering the correct activities based on the users input
+ """
+ log.info(u'PowerpointController loaded')
+
+ def __init__(self, plugin):
+ """
+ Initialise the class
+ """
+ log.debug(u'Initialising')
+ PresentationController.__init__(self, plugin, u'Powerpoint',
+ PowerpointDocument)
+ self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
+ self.process = None
+
+ def check_available(self):
+ """
+ PowerPoint is able to run on this machine
+ """
+ log.debug(u'check_available')
+ return True
+ #return False
+
+
+ def start_process(self):
+ """
+ Loads PowerPoint process
+ """
+ log.debug(u'start_process')
+ if not self.process:
+ self.process = app(id='com.microsoft.powerpoint')
+ self.process.relaunchmode = 'always'
+ self.process.start_up_dialog.set(False)
+ #self.process.Visible = True
+ #self.process.WindowState = 2
+ self.apply_app_settings()
+
+ def kill(self):
+ """
+ Called at system exit to clean up any running presentations
+ """
+ log.debug(u'Kill powerpoint')
+ while self.docs:
+ self.docs[0].close_presentation()
+ if self.process is None:
+ return
+ #TODO this doesnt worok right
+ try:
+ if self.process and len(self.process.presentations()) > 0:
+ return
+ self.process.quit()
+ #except pywintypes.com_error:
+ except:
+ pass
+ self.process = None
+
+ def apply_app_settings(self):
+ """
+ Apply settings for PowerPoint
+ 14\Options\Options\Save graphics screen heigth = 240
+ 14\Options\Options\Save graphics screen width = 320
+ 14\Options\Options\Save only current slide graphics = 0
+
+ """
+ openlp_settings = Settings("openlp.org","OpenLP")
+ ppt_settings = Settings("Microsoft", "Powerpoint")
+# use_secondary = int(keynote_settings.value(u'PresentationModeUseSecondary', u''))
+# monitor = openlp_settings.value( u'general/monitor', 0)
+# display_on_monitor = openlp_settings.value( u'general/display on monitor', False)
+# if display_on_monitor and use_secondary <> monitor:
+# keynote_settings.setValue(u'PresentationModeUseSecondary', unicode(monitor))
+# elif not display_on_monitor and use_secondary > 0:
+# keynote_settings.setValue(u'PresentationModeUseSecondary', u'0')
+# show_presenter_view = openlp_settings.value(self.plugin.settingsSection + u'/show presenter view', False)
+# keynote_feedback_display = keynote_settings.value(u'PresentationModeEnableFeedbackDisplay', False)
+# if show_presenter_view <> keynote_feedback_display:
+# keynote_settings.setValue(u'PresentationModeEnableFeedbackDisplay', show_presenter_view)
+
+
+class PowerpointDocument(PresentationDocument):
+ """
+ Class which holds information and controls a single presentation
+ """
+
+ def __init__(self, controller, presentation):
+ """
+ Constructor, store information about the file and initialise
+ """
+ log.debug(u'Init Presentation Powerpoint')
+ PresentationDocument.__init__(self, controller, presentation)
+ self.presentation = None
+
+ def load_presentation(self):
+ """
+ Called when a presentation is added to the SlideController.
+ Opens the PowerPoint file using the process created earlier.
+ """
+ log.debug(u'load_presentation')
+ if not self.controller.process or not self.controller.process.isrunning():
+ self.controller.start_process()
+ try:
+ self.controller.process.open(self.filepath)
+ #except pywintypes.com_error:
+ except:
+ log.debug(u'PPT open failed')
+ return False
+ self.presentation = self.controller.process.presentations[
+ len(self.controller.process.presentations())-1]
+ self.create_thumbnails()
+ return True
+
+ def create_thumbnails(self):
+ """
+ Create the thumbnail images for the current presentation.
+
+ Note an alternative and quicker method would be do::
+
+ self.presentation.Slides[n].Copy()
+ thumbnail = QApplication.clipboard.image()
+
+ However, for the moment, we want a physical file since it makes life
+ easier elsewhere.
+ """
+ log.debug(u'create_thumbnails')
+ if self.check_thumbnails():
+ return
+ get_thumbnail_folder = self.get_thumbnail_folder()
+ self.presentation.save(in_=get_thumbnail_folder, as_=k.save_as_PNG)
+ slide_no = 0
+ temp_dir = os.path.join(get_thumbnail_folder, self.get_file_name())
+ for filename in os.listdir(temp_dir):
+ full_filename = os.path.join(temp_dir, filename)
+ if not os.path.isfile(full_filename) or not filename.endswith(u'.png') or filename == u'icon.png':
+ continue
+ slide_no = slide_no + 1
+ if not filename.startswith(self.controller.thumbnail_prefix):
+ path = os.path.join(get_thumbnail_folder,
+ self.controller.thumbnail_prefix + unicode(slide_no) + u'.png')
+ try:
+ os.rename(full_filename, path)
+ except:
+ open(path,'w').write(open(full_filename,'r').read())
+ os.unlink(full_filename)
+ try:
+ shutil.rmtree(temp_dir)
+ except:
+ pass
+
+ def close_presentation(self):
+ """
+ Close presentation and clean up objects. This is triggered by a new
+ object being added to SlideController or OpenLP being shut down.
+ """
+ log.debug(u'ClosePresentation')
+ if self.presentation:
+ try:
+ self.presentation.close()
+ except:
+ pass
+ self.presentation = None
+ self.controller.remove_doc(self)
+
+ def is_loaded(self):
+ """
+ Returns ``True`` if a presentation is loaded.
+ """
+ log.debug(u'is_loaded')
+ try:
+ if not self.controller.process.isrunning():
+ return False
+ if len(self.controller.process.document_windows()) == 0:
+ return False
+ if len(self.controller.process.presentations()) == 0:
+ return False
+ except:
+ return False
+ presentations = self.controller.process.presentations()
+ for presentation in presentations:
+ name = presentation.name()
+ basename = os.path.basename(self.filepath)
+ if basename == name:
+ return True
+ return False
+
+ def is_active(self):
+ """
+ Returns ``True`` if a presentation is currently active.
+ """
+ log.debug(u'is_active')
+ if not self.is_loaded():
+ return False
+ try:
+ slide_show_window = self.presentation.slide_show_window
+ if slide_show_window is None:
+ return False
+ slide_state = self.presentation.slide_show_window.slideshow_view.slide_state()
+ if slide_state is None or slide_state == k.missing_value:
+ return False
+ except:
+ return False
+ return True
+
+ def unblank_screen(self):
+ """
+ Unblanks (restores) the presentation.
+ """
+ log.debug(u'unblank_screen')
+ if self.is_blank():
+ settings = self.presentation.slide_show_settings
+ #settings.run_slide_show()
+ self.presentation.slide_show_window.slideshow_view.slide_state.set(k.slide_show_state_running)
+ self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
+ self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
+
+ def blank_screen(self):
+ """
+ Blanks the screen.
+ """
+ log.debug(u'blank_screen')
+ self.presentation.slide_show_window.slideshow_view.slide_state.set(k.slide_show_state_black_screen)
+
+ def is_blank(self):
+ """
+ Returns ``True`` if screen is blank.
+ """
+ log.debug(u'is_blank')
+ if self.is_active() and self.presentation.slide_show_window.slideshow_view\
+ .slide_state() is k.slide_show_state_black_screen:
+ return True
+ else:
+ return False
+
+ def stop_presentation(self):
+ """
+ Stops the current presentation and hides the output.
+ """
+ log.debug(u'stop_presentation')
+ self.presentation.slide_show_window.slideshow_view.exit_slide_show()
+
+
+ def start_presentation(self):
+ """
+ Starts a presentation from the beginning.
+ """
+ log.debug(u'start_presentation')
+ renderer = self.controller.plugin.renderer
+ rect = renderer.screens.current[u'size']
+ ppt_settings = self.presentation.slide_show_settings
+ openlp_settings = Settings("openlp.org","OpenLP")
+ show_presenter_view = openlp_settings.value(self.controller.plugin.settingsSection + u'/show presenter view', False)
+ override_position = openlp_settings.value( u'general/override position', False)
+ if show_presenter_view:
+ ppt_settings.show_type.set(k.slide_show_type_presenter)
+ elif override_position:
+ ppt_settings.show_type.set(k.slide_show_type_window)
+ else:
+ ppt_settings.show_type.set(k.slide_show_type_kiosk)
+ #ppt_settings.show_type.set(k.slide_show_type_speaker)
+ ppt_window = ppt_settings.run_slide_show()
+ if ppt_window.slideshow_view.slide_state() != k.slide_show_state_running:
+ ppt_window.slideshow_view.slide_state.set(k.slide_show_state_running)
+# slide_state = ppt_window.slideshow_view.slide_state()
+# slide_state = ppt_window.slideshow_view.slide_state()
+ if not ppt_window or show_presenter_view:
+ return
+ if override_position:
+ top = float(rect.y())
+ height = float(rect.height())
+ left_position = float(rect.x())
+ width = float(rect.width())
+ ppt_window.top.set(top)
+ ppt_window.height.set(height)
+ ppt_window.left_position.set(left_position)
+ ppt_window.width.set(width)
+ else:
+ #TODO set output monitor for fullscreen mode
+ pass
+
+ def get_slide_number(self):
+ """
+ Returns the current slide number.
+ """
+ log.debug(u'get_slide_number')
+ return self.presentation.slide_show_window.slideshow_view.current_show_position()
+
+ def get_slide_count(self):
+ """
+ Returns total number of slides.
+ """
+ log.debug(u'get_slide_count')
+ return len(self.presentation.slides())
+
+ def goto_slide(self, slideno):
+ """
+ Moves to a specific slide in the presentation.
+ """
+ log.debug(u'goto_slide')
+ #TODO this works. but needs to fix this dumb code
+ while self.get_slide_number() <> slideno:
+ if self.get_slide_number() < slideno:
+ self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
+ else:
+ self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
+ self.controller.process.activate()
+
+ def next_step(self):
+ """
+ Triggers the next effect of slide on the running presentation.
+ """
+ log.debug(u'next_step')
+ self.presentation.slide_show_window.slideshow_view.go_to_next_slide()
+ self.controller.process.activate()
+ if self.get_slide_number() > self.get_slide_count():
+ self.previous_step()
+
+ def previous_step(self):
+ """
+ Triggers the previous slide on the running presentation.
+ """
+ log.debug(u'previous_step')
+ self.presentation.slide_show_window.slideshow_view.go_to_previous_slide()
+ self.controller.process.activate()
+
+ def get_slide_text(self, slide_no):
+ """
+ Returns the text on the slide.
+
+ ``slide_no``
+ The slide the text is required for, starting at 1.
+ """
+ return _get_text_from_shapes(self.presentation.slides[slide_no-1].shapes)
+
+ def get_slide_notes(self, slide_no):
+ """
+ Returns the text on the slide.
+
+ ``slide_no``
+ The slide the notes are required for, starting at 1.
+ """
+ return _get_text_from_shapes(
+ self.presentation.slides[slide_no].notes_page.shapes())
+
+def _get_text_from_shapes(shapes):
+ """
+ Returns any text extracted from the shapes on a presentation slide.
+
+ ``shapes``
+ A set of shapes to search for text.
+ """
+ text = ''
+ for idx in range(len(shapes)):
+ shape = shapes[idx + 1]
+ if shape.has_text_frame():
+ text += shape.text_frame.text_range.content() + '\n'
+ return text
=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
--- openlp/plugins/presentations/lib/presentationtab.py 2013-01-05 22:17:30 +0000
+++ openlp/plugins/presentations/lib/presentationtab.py 2013-01-15 19:35:24 +0000
@@ -31,6 +31,7 @@
from openlp.core.lib import Receiver, Settings, SettingsTab, translate
from openlp.core.lib.ui import UiStrings
+import sys
class PresentationTab(SettingsTab):
"""
@@ -70,6 +71,11 @@
self.OverrideAppCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox)
self.OverrideAppCheckBox.setObjectName(u'OverrideAppCheckBox')
self.AdvancedLayout.addWidget(self.OverrideAppCheckBox)
+ self.ShowPresenterViewCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox)
+ self.ShowPresenterViewCheckBox.setObjectName(u'ShowPresenterViewCheckBox')
+ self.AdvancedLayout.addWidget(self.ShowPresenterViewCheckBox)
+ if not sys.platform.startswith('darwin'):
+ self.ShowPresenterViewCheckBox.setVisible(False)
self.leftLayout.addWidget(self.AdvancedGroupBox)
self.leftLayout.addStretch()
self.rightLayout.addStretch()
@@ -86,6 +92,8 @@
self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
self.OverrideAppCheckBox.setText(
translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
+ self.ShowPresenterViewCheckBox.setText(
+ translate('PresentationPlugin.PresentationTab', 'Show Presenter View'))
def setControllerText(self, checkbox, controller):
if checkbox.isEnabled():
@@ -104,6 +112,8 @@
checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name, QtCore.Qt.Checked))
self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app',
QtCore.Qt.Unchecked))
+ self.ShowPresenterViewCheckBox.setChecked(Settings().value(self.settingsSection + u'/show presenter view',
+ QtCore.Qt.Unchecked))
def save(self):
"""
@@ -130,6 +140,10 @@
if Settings().value(setting_key, QtCore.Qt.Checked) != self.OverrideAppCheckBox.checkState():
Settings().setValue(setting_key, self.OverrideAppCheckBox.checkState())
changed = True
+ setting_key = self.settingsSection + u'/show presenter view'
+ if Settings().value(setting_key, QtCore.Qt.Unchecked) != self.ShowPresenterViewCheckBox.checkState():
+ Settings().setValue(setting_key, self.ShowPresenterViewCheckBox.isChecked())
+ changed = True
if changed:
self.parent.resetSupportedSuffixes()
Receiver.send_message(u'mediaitem_presentation_rebuild')
=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py 2013-01-05 22:17:30 +0000
+++ openlp/plugins/presentations/presentationplugin.py 2013-01-15 19:35:24 +0000
@@ -31,6 +31,7 @@
presentations from a variety of document formats.
"""
import os
+import sys
import logging
from openlp.core.lib import Plugin, StringContent, build_icon, translate
@@ -120,6 +121,12 @@
u'presentations', u'lib')
for filename in os.listdir(controller_dir):
if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':
+ if not sys.platform.startswith('darwin') and filename == 'powerpointmaccontroller.py':
+ continue
+ if not sys.platform.startswith('darwin') and filename == 'keynotemaccontroller.py':
+ continue
+ if not sys.platform.startswith('win') and filename == 'powerpointcontroller.py':
+ continue
path = os.path.join(controller_dir, filename)
if os.path.isfile(path):
modulename = u'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]
Follow ups