forked from openlp/openlp
songusage and presentation code standards
This commit is contained in:
parent
0ceaef7a51
commit
dad243dd74
@ -27,6 +27,6 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`presentations` module provides the Presentations plugin which allows
|
The :mod:`presentations` module provides the Presentations plugin which allows OpenLP to show presentations from most
|
||||||
OpenLP to show presentations from most popular presentation packages.
|
popular presentation packages.
|
||||||
"""
|
"""
|
||||||
|
@ -62,13 +62,14 @@ from openlp.core.lib import ScreenList
|
|||||||
from openlp.core.utils import delete_file, get_uno_command, get_uno_instance
|
from openlp.core.utils import delete_file, get_uno_command, get_uno_instance
|
||||||
from presentationcontroller import PresentationController, PresentationDocument
|
from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ImpressController(PresentationController):
|
class ImpressController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with Impress presentations.
|
Class to control interactions with Impress presentations. It creates the runtime environment, loads and closes the
|
||||||
It creates the runtime environment, loads and closes the presentation as
|
presentation as well as triggering the correct activities based on the users input.
|
||||||
well as triggering the correct activities based on the users input
|
|
||||||
"""
|
"""
|
||||||
log.info(u'ImpressController loaded')
|
log.info(u'ImpressController loaded')
|
||||||
|
|
||||||
@ -79,14 +80,14 @@ class ImpressController(PresentationController):
|
|||||||
log.debug(u'Initialising')
|
log.debug(u'Initialising')
|
||||||
PresentationController.__init__(self, plugin, u'Impress', ImpressDocument)
|
PresentationController.__init__(self, plugin, u'Impress', ImpressDocument)
|
||||||
self.supports = [u'odp']
|
self.supports = [u'odp']
|
||||||
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
self.also_supports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
||||||
self.process = None
|
self.process = None
|
||||||
self.desktop = None
|
self.desktop = None
|
||||||
self.manager = None
|
self.manager = None
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
Impress is able to run on this machine
|
Impress is able to run on this machine.
|
||||||
"""
|
"""
|
||||||
log.debug(u'check_available')
|
log.debug(u'check_available')
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
@ -96,9 +97,8 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
def start_process(self):
|
def start_process(self):
|
||||||
"""
|
"""
|
||||||
Loads a running version of OpenOffice in the background.
|
Loads a running version of OpenOffice in the background. It is not displayed to the user but is available to the
|
||||||
It is not displayed to the user but is available to the UNO interface
|
UNO interface when required.
|
||||||
when required.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'start process Openoffice')
|
log.debug(u'start process Openoffice')
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
@ -113,8 +113,7 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
def get_uno_desktop(self):
|
def get_uno_desktop(self):
|
||||||
"""
|
"""
|
||||||
On non-Windows platforms, use Uno. Get the OpenOffice desktop
|
On non-Windows platforms, use Uno. Get the OpenOffice desktop which will be used to manage impress.
|
||||||
which will be used to manage impress
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'get UNO Desktop Openoffice')
|
log.debug(u'get UNO Desktop Openoffice')
|
||||||
uno_instance = None
|
uno_instance = None
|
||||||
@ -132,8 +131,7 @@ class ImpressController(PresentationController):
|
|||||||
loop += 1
|
loop += 1
|
||||||
try:
|
try:
|
||||||
self.manager = uno_instance.ServiceManager
|
self.manager = uno_instance.ServiceManager
|
||||||
log.debug(u'get UNO Desktop Openoffice - createInstanceWithContext'
|
log.debug(u'get UNO Desktop Openoffice - createInstanceWithContext - Desktop')
|
||||||
u' - Desktop')
|
|
||||||
desktop = self.manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance)
|
desktop = self.manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance)
|
||||||
return desktop
|
return desktop
|
||||||
except:
|
except:
|
||||||
@ -142,8 +140,7 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
def get_com_desktop(self):
|
def get_com_desktop(self):
|
||||||
"""
|
"""
|
||||||
On Windows platforms, use COM. Return the desktop object which
|
On Windows platforms, use COM. Return the desktop object which will be used to manage Impress.
|
||||||
will be used to manage Impress
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'get COM Desktop OpenOffice')
|
log.debug(u'get COM Desktop OpenOffice')
|
||||||
if not self.manager:
|
if not self.manager:
|
||||||
@ -157,7 +154,7 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
def get_com_servicemanager(self):
|
def get_com_servicemanager(self):
|
||||||
"""
|
"""
|
||||||
Return the OOo service manager for windows
|
Return the OOo service manager for windows.
|
||||||
"""
|
"""
|
||||||
log.debug(u'get_com_servicemanager openoffice')
|
log.debug(u'get_com_servicemanager openoffice')
|
||||||
try:
|
try:
|
||||||
@ -168,7 +165,7 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
"""
|
"""
|
||||||
Called at system exit to clean up any running presentations
|
Called at system exit to clean up any running presentations.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Kill OpenOffice')
|
log.debug(u'Kill OpenOffice')
|
||||||
while self.docs:
|
while self.docs:
|
||||||
@ -203,12 +200,12 @@ class ImpressController(PresentationController):
|
|||||||
|
|
||||||
class ImpressDocument(PresentationDocument):
|
class ImpressDocument(PresentationDocument):
|
||||||
"""
|
"""
|
||||||
Class which holds information and controls a single presentation
|
Class which holds information and controls a single presentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, controller, presentation):
|
def __init__(self, controller, presentation):
|
||||||
"""
|
"""
|
||||||
Constructor, store information about the file and initialise
|
Constructor, store information about the file and initialise.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Init Presentation OpenOffice')
|
log.debug(u'Init Presentation OpenOffice')
|
||||||
PresentationDocument.__init__(self, controller, presentation)
|
PresentationDocument.__init__(self, controller, presentation)
|
||||||
@ -218,11 +215,9 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def load_presentation(self):
|
def load_presentation(self):
|
||||||
"""
|
"""
|
||||||
Called when a presentation is added to the SlideController.
|
Called when a presentation is added to the SlideController. It builds the environment, starts communcations with
|
||||||
It builds the environment, starts communcations with the background
|
the background OpenOffice task started earlier. If OpenOffice is not present is is started. Once the environment
|
||||||
OpenOffice task started earlier. If OpenOffice is not present is is
|
is available the presentation is loaded and started.
|
||||||
started. Once the environment is available the presentation is loaded
|
|
||||||
and started.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'Load Presentation OpenOffice')
|
log.debug(u'Load Presentation OpenOffice')
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
@ -239,13 +234,12 @@ class ImpressDocument(PresentationDocument):
|
|||||||
self.desktop = desktop
|
self.desktop = desktop
|
||||||
properties = []
|
properties = []
|
||||||
if os.name != u'nt':
|
if os.name != u'nt':
|
||||||
# Recent versions of Impress on Windows won't start the presentation
|
# Recent versions of Impress on Windows won't start the presentation if it starts as minimized. It seems OK
|
||||||
# if it starts as minimized. It seems OK on Linux though.
|
# on Linux though.
|
||||||
properties.append(self.create_property(u'Minimized', True))
|
properties.append(self.create_property(u'Minimized', True))
|
||||||
properties = tuple(properties)
|
properties = tuple(properties)
|
||||||
try:
|
try:
|
||||||
self.document = desktop.loadComponentFromURL(url, u'_blank',
|
self.document = desktop.loadComponentFromURL(url, u'_blank', 0, properties)
|
||||||
0, properties)
|
|
||||||
except:
|
except:
|
||||||
log.warn(u'Failed to load presentation %s' % url)
|
log.warn(u'Failed to load presentation %s' % url)
|
||||||
return False
|
return False
|
||||||
@ -262,33 +256,33 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def create_thumbnails(self):
|
def create_thumbnails(self):
|
||||||
"""
|
"""
|
||||||
Create thumbnail images for presentation
|
Create thumbnail images for presentation.
|
||||||
"""
|
"""
|
||||||
log.debug(u'create thumbnails OpenOffice')
|
log.debug(u'create thumbnails OpenOffice')
|
||||||
if self.check_thumbnails():
|
if self.check_thumbnails():
|
||||||
return
|
return
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
thumbdirurl = u'file:///' + self.get_temp_folder().replace(u'\\', u'/') \
|
thumb_dir_url = u'file:///' + self.get_temp_folder().replace(u'\\', u'/') \
|
||||||
.replace(u':', u'|').replace(u' ', u'%20')
|
.replace(u':', u'|').replace(u' ', u'%20')
|
||||||
else:
|
else:
|
||||||
thumbdirurl = uno.systemPathToFileUrl(self.get_temp_folder())
|
thumb_dir_url = uno.systemPathToFileUrl(self.get_temp_folder())
|
||||||
props = []
|
properties = []
|
||||||
props.append(self.create_property(u'FilterName', u'impress_png_Export'))
|
properties.append(self.create_property(u'FilterName', u'impress_png_Export'))
|
||||||
props = tuple(props)
|
properties = tuple(properties)
|
||||||
doc = self.document
|
doc = self.document
|
||||||
pages = doc.getDrawPages()
|
pages = doc.getDrawPages()
|
||||||
if not pages:
|
if not pages:
|
||||||
return
|
return
|
||||||
if not os.path.isdir(self.get_temp_folder()):
|
if not os.path.isdir(self.get_temp_folder()):
|
||||||
os.makedirs(self.get_temp_folder())
|
os.makedirs(self.get_temp_folder())
|
||||||
for idx in range(pages.getCount()):
|
for index in range(pages.getCount()):
|
||||||
page = pages.getByIndex(idx)
|
page = pages.getByIndex(index)
|
||||||
doc.getCurrentController().setCurrentPage(page)
|
doc.getCurrentController().setCurrentPage(page)
|
||||||
urlpath = u'%s/%s.png' % (thumbdirurl, unicode(idx + 1))
|
url_path = u'%s/%s.png' % (thumb_dir_url, unicode(index + 1))
|
||||||
path = os.path.join(self.get_temp_folder(), unicode(idx + 1) + u'.png')
|
path = os.path.join(self.get_temp_folder(), unicode(index + 1) + u'.png')
|
||||||
try:
|
try:
|
||||||
doc.storeToURL(urlpath, props)
|
doc.storeToURL(url_path, properties)
|
||||||
self.convert_thumbnail(path, idx + 1)
|
self.convert_thumbnail(path, index + 1)
|
||||||
delete_file(path)
|
delete_file(path)
|
||||||
except ErrorCodeIOException, exception:
|
except ErrorCodeIOException, exception:
|
||||||
log.exception(u'ERROR! ErrorCodeIOException %d' % exception.ErrCode)
|
log.exception(u'ERROR! ErrorCodeIOException %d' % exception.ErrCode)
|
||||||
@ -297,23 +291,21 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def create_property(self, name, value):
|
def create_property(self, name, value):
|
||||||
"""
|
"""
|
||||||
Create an OOo style property object which are passed into some
|
Create an OOo style property object which are passed into some Uno methods.
|
||||||
Uno methods
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'create property OpenOffice')
|
log.debug(u'create property OpenOffice')
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
prop = self.controller.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
|
property = self.controller.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
|
||||||
else:
|
else:
|
||||||
prop = PropertyValue()
|
property = PropertyValue()
|
||||||
prop.Name = name
|
property.Name = name
|
||||||
prop.Value = value
|
property.Value = value
|
||||||
return prop
|
return property
|
||||||
|
|
||||||
def close_presentation(self):
|
def close_presentation(self):
|
||||||
"""
|
"""
|
||||||
Close presentation and clean up objects
|
Close presentation and clean up objects. Triggered by new object being added to SlideController or OpenLP being
|
||||||
Triggered by new object being added to SlideController or OpenLP
|
shutdown.
|
||||||
being shutdown
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'close Presentation OpenOffice')
|
log.debug(u'close Presentation OpenOffice')
|
||||||
if self.document:
|
if self.document:
|
||||||
@ -329,7 +321,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
"""
|
"""
|
||||||
Returns true if a presentation is loaded
|
Returns true if a presentation is loaded.
|
||||||
"""
|
"""
|
||||||
log.debug(u'is loaded OpenOffice')
|
log.debug(u'is loaded OpenOffice')
|
||||||
if self.presentation is None or self.document is None:
|
if self.presentation is None or self.document is None:
|
||||||
@ -346,7 +338,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
"""
|
"""
|
||||||
Returns true if a presentation is active and running
|
Returns true if a presentation is active and running.
|
||||||
"""
|
"""
|
||||||
log.debug(u'is active OpenOffice')
|
log.debug(u'is active OpenOffice')
|
||||||
if not self.is_loaded():
|
if not self.is_loaded():
|
||||||
@ -355,21 +347,21 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def unblank_screen(self):
|
def unblank_screen(self):
|
||||||
"""
|
"""
|
||||||
Unblanks the screen
|
Unblanks the screen.
|
||||||
"""
|
"""
|
||||||
log.debug(u'unblank screen OpenOffice')
|
log.debug(u'unblank screen OpenOffice')
|
||||||
return self.control.resume()
|
return self.control.resume()
|
||||||
|
|
||||||
def blank_screen(self):
|
def blank_screen(self):
|
||||||
"""
|
"""
|
||||||
Blanks the screen
|
Blanks the screen.
|
||||||
"""
|
"""
|
||||||
log.debug(u'blank screen OpenOffice')
|
log.debug(u'blank screen OpenOffice')
|
||||||
self.control.blankScreen(0)
|
self.control.blankScreen(0)
|
||||||
|
|
||||||
def is_blank(self):
|
def is_blank(self):
|
||||||
"""
|
"""
|
||||||
Returns true if screen is blank
|
Returns true if screen is blank.
|
||||||
"""
|
"""
|
||||||
log.debug(u'is blank OpenOffice')
|
log.debug(u'is blank OpenOffice')
|
||||||
if self.control and self.control.isRunning():
|
if self.control and self.control.isRunning():
|
||||||
@ -379,7 +371,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def stop_presentation(self):
|
def stop_presentation(self):
|
||||||
"""
|
"""
|
||||||
Stop the presentation, remove from screen
|
Stop the presentation, remove from screen.
|
||||||
"""
|
"""
|
||||||
log.debug(u'stop presentation OpenOffice')
|
log.debug(u'stop presentation OpenOffice')
|
||||||
# deactivate should hide the screen according to docs, but doesn't
|
# deactivate should hide the screen according to docs, but doesn't
|
||||||
@ -389,18 +381,17 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def start_presentation(self):
|
def start_presentation(self):
|
||||||
"""
|
"""
|
||||||
Start the presentation from the beginning
|
Start the presentation from the beginning.
|
||||||
"""
|
"""
|
||||||
log.debug(u'start presentation OpenOffice')
|
log.debug(u'start presentation OpenOffice')
|
||||||
if self.control is None or not self.control.isRunning():
|
if self.control is None or not self.control.isRunning():
|
||||||
self.presentation.start()
|
self.presentation.start()
|
||||||
self.control = self.presentation.getController()
|
self.control = self.presentation.getController()
|
||||||
# start() returns before the Component is ready.
|
# start() returns before the Component is ready. Try for 15 seconds.
|
||||||
# Try for 15 seconds
|
sleep_count = 1
|
||||||
i = 1
|
while not self.control and sleep_count < 150:
|
||||||
while not self.control and i < 150:
|
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
i += 1
|
sleep_count += 1
|
||||||
self.control = self.presentation.getController()
|
self.control = self.presentation.getController()
|
||||||
else:
|
else:
|
||||||
self.control.activate()
|
self.control.activate()
|
||||||
@ -408,25 +399,25 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def get_slide_number(self):
|
def get_slide_number(self):
|
||||||
"""
|
"""
|
||||||
Return the current slide number on the screen, from 1
|
Return the current slide number on the screen, from 1.
|
||||||
"""
|
"""
|
||||||
return self.control.getCurrentSlideIndex() + 1
|
return self.control.getCurrentSlideIndex() + 1
|
||||||
|
|
||||||
def get_slide_count(self):
|
def get_slide_count(self):
|
||||||
"""
|
"""
|
||||||
Return the total number of slides
|
Return the total number of slides.
|
||||||
"""
|
"""
|
||||||
return self.document.getDrawPages().getCount()
|
return self.document.getDrawPages().getCount()
|
||||||
|
|
||||||
def goto_slide(self, slideno):
|
def goto_slide(self, slideno):
|
||||||
"""
|
"""
|
||||||
Go to a specific slide (from 1)
|
Go to a specific slide (from 1).
|
||||||
"""
|
"""
|
||||||
self.control.gotoSlideIndex(slideno-1)
|
self.control.gotoSlideIndex(slideno-1)
|
||||||
|
|
||||||
def next_step(self):
|
def next_step(self):
|
||||||
"""
|
"""
|
||||||
Triggers the next effect of slide on the running presentation
|
Triggers the next effect of slide on the running presentation.
|
||||||
"""
|
"""
|
||||||
is_paused = self.control.isPaused()
|
is_paused = self.control.isPaused()
|
||||||
self.control.gotoNextEffect()
|
self.control.gotoNextEffect()
|
||||||
@ -436,7 +427,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
|
|
||||||
def previous_step(self):
|
def previous_step(self):
|
||||||
"""
|
"""
|
||||||
Triggers the previous slide on the running presentation
|
Triggers the previous slide on the running presentation.
|
||||||
"""
|
"""
|
||||||
self.control.gotoPreviousSlide()
|
self.control.gotoPreviousSlide()
|
||||||
|
|
||||||
@ -470,8 +461,8 @@ class ImpressDocument(PresentationDocument):
|
|||||||
page = pages.getByIndex(slide_no - 1)
|
page = pages.getByIndex(slide_no - 1)
|
||||||
if notes:
|
if notes:
|
||||||
page = page.getNotesPage()
|
page = page.getNotesPage()
|
||||||
for idx in range(page.getCount()):
|
for index in range(page.getCount()):
|
||||||
shape = page.getByIndex(idx)
|
shape = page.getByIndex(index)
|
||||||
if shape.supportsService("com.sun.star.drawing.Text"):
|
if shape.supportsService("com.sun.star.drawing.Text"):
|
||||||
text += shape.getString() + '\n'
|
text += shape.getString() + '\n'
|
||||||
return text
|
return text
|
||||||
|
@ -38,14 +38,17 @@ from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adj
|
|||||||
from openlp.core.utils import get_locale_key
|
from openlp.core.utils import get_locale_key
|
||||||
from openlp.plugins.presentations.lib import MessageListener
|
from openlp.plugins.presentations.lib import MessageListener
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
ERROR = QtGui.QImage(u':/general/general_delete.png')
|
|
||||||
|
ERROR_IMAGE = QtGui.QImage(u':/general/general_delete.png')
|
||||||
|
|
||||||
|
|
||||||
class PresentationMediaItem(MediaManagerItem):
|
class PresentationMediaItem(MediaManagerItem):
|
||||||
"""
|
"""
|
||||||
This is the Presentation media manager item for Presentation Items.
|
This is the Presentation media manager item for Presentation Items. It can present files using Openoffice and
|
||||||
It can present files using Openoffice and Powerpoint
|
Powerpoint
|
||||||
"""
|
"""
|
||||||
log.info(u'Presentations Media Item loaded')
|
log.info(u'Presentations Media Item loaded')
|
||||||
|
|
||||||
@ -71,25 +74,25 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
self.on_new_prompt = translate('PresentationPlugin.MediaItem', 'Select Presentation(s)')
|
self.on_new_prompt = translate('PresentationPlugin.MediaItem', 'Select Presentation(s)')
|
||||||
self.Automatic = translate('PresentationPlugin.MediaItem', 'Automatic')
|
self.Automatic = translate('PresentationPlugin.MediaItem', 'Automatic')
|
||||||
self.displayTypeLabel.setText(translate('PresentationPlugin.MediaItem', 'Present using:'))
|
self.display_type_label.setText(translate('PresentationPlugin.MediaItem', 'Present using:'))
|
||||||
|
|
||||||
def build_file_mask_string(self):
|
def build_file_mask_string(self):
|
||||||
"""
|
"""
|
||||||
Build the list of file extensions to be used in the Open file dialog
|
Build the list of file extensions to be used in the Open file dialog.
|
||||||
"""
|
"""
|
||||||
fileType = u''
|
file_type = u''
|
||||||
for controller in self.controllers:
|
for controller in self.controllers:
|
||||||
if self.controllers[controller].enabled():
|
if self.controllers[controller].enabled():
|
||||||
types = self.controllers[controller].supports + self.controllers[controller].alsosupports
|
file_types = self.controllers[controller].supports + self.controllers[controller].also_supports
|
||||||
for type in types:
|
for file_type in file_types:
|
||||||
if fileType.find(type) == -1:
|
if file_type.find(file_type) == -1:
|
||||||
fileType += u'*.%s ' % type
|
file_type += u'*.%s ' % file_type
|
||||||
self.service_manager.supported_suffixes(type)
|
self.service_manager.supported_suffixes(file_type)
|
||||||
self.on_new_file_masks = translate('PresentationPlugin.MediaItem', 'Presentations (%s)') % fileType
|
self.on_new_file_masks = translate('PresentationPlugin.MediaItem', 'Presentations (%s)') % file_type
|
||||||
|
|
||||||
def required_icons(self):
|
def required_icons(self):
|
||||||
"""
|
"""
|
||||||
Set which icons the media manager tab should show
|
Set which icons the media manager tab should show.
|
||||||
"""
|
"""
|
||||||
MediaManagerItem.required_icons(self)
|
MediaManagerItem.required_icons(self)
|
||||||
self.has_file_icon = True
|
self.has_file_icon = True
|
||||||
@ -98,21 +101,21 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def add_end_header_bar(self):
|
def add_end_header_bar(self):
|
||||||
"""
|
"""
|
||||||
Display custom media manager items for presentations
|
Display custom media manager items for presentations.
|
||||||
"""
|
"""
|
||||||
self.presentationWidget = QtGui.QWidget(self)
|
self.presentation_widget = QtGui.QWidget(self)
|
||||||
self.presentationWidget.setObjectName(u'presentationWidget')
|
self.presentation_widget.setObjectName(u'presentation_widget')
|
||||||
self.displayLayout = QtGui.QFormLayout(self.presentationWidget)
|
self.display_layout = QtGui.QFormLayout(self.presentation_widget)
|
||||||
self.displayLayout.setMargin(self.displayLayout.spacing())
|
self.display_layout.setMargin(self.display_layout.spacing())
|
||||||
self.displayLayout.setObjectName(u'displayLayout')
|
self.display_layout.setObjectName(u'display_layout')
|
||||||
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
|
self.display_type_label = QtGui.QLabel(self.presentation_widget)
|
||||||
self.displayTypeLabel.setObjectName(u'displayTypeLabel')
|
self.display_type_label.setObjectName(u'display_type_label')
|
||||||
self.displayTypeComboBox = create_horizontal_adjusting_combo_box(self.presentationWidget,
|
self.displayTypeComboBox = create_horizontal_adjusting_combo_box(self.presentation_widget,
|
||||||
u'displayTypeComboBox')
|
u'displayTypeComboBox')
|
||||||
self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
|
self.display_type_label.setBuddy(self.displayTypeComboBox)
|
||||||
self.displayLayout.addRow(self.displayTypeLabel, self.displayTypeComboBox)
|
self.display_layout.addRow(self.display_type_label, self.displayTypeComboBox)
|
||||||
# Add the Presentation widget to the page layout
|
# Add the Presentation widget to the page layout
|
||||||
self.page_layout.addWidget(self.presentationWidget)
|
self.page_layout.addWidget(self.presentation_widget)
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
"""
|
"""
|
||||||
@ -120,13 +123,13 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
||||||
files = Settings().value(self.settings_section + u'/presentations files')
|
files = Settings().value(self.settings_section + u'/presentations files')
|
||||||
self.load_list(files, initialLoad=True)
|
self.load_list(files, initial_load=True)
|
||||||
self.populate_display_types()
|
self.populate_display_types()
|
||||||
|
|
||||||
def populate_display_types(self):
|
def populate_display_types(self):
|
||||||
"""
|
"""
|
||||||
Load the combobox with the enabled presentation controllers,
|
Load the combobox with the enabled presentation controllers, allowing user to select a specific app if settings
|
||||||
allowing user to select a specific app if settings allow
|
allow.
|
||||||
"""
|
"""
|
||||||
self.displayTypeComboBox.clear()
|
self.displayTypeComboBox.clear()
|
||||||
for item in self.controllers:
|
for item in self.controllers:
|
||||||
@ -137,38 +140,37 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
self.displayTypeComboBox.insertItem(0, self.Automatic)
|
self.displayTypeComboBox.insertItem(0, self.Automatic)
|
||||||
self.displayTypeComboBox.setCurrentIndex(0)
|
self.displayTypeComboBox.setCurrentIndex(0)
|
||||||
if Settings().value(self.settings_section + u'/override app') == QtCore.Qt.Checked:
|
if Settings().value(self.settings_section + u'/override app') == QtCore.Qt.Checked:
|
||||||
self.presentationWidget.show()
|
self.presentation_widget.show()
|
||||||
else:
|
else:
|
||||||
self.presentationWidget.hide()
|
self.presentation_widget.hide()
|
||||||
|
|
||||||
def load_list(self, files, target_group=None, initialLoad=False):
|
def load_list(self, files, target_group=None, initial_load=False):
|
||||||
"""
|
"""
|
||||||
Add presentations into the media manager
|
Add presentations into the media manager. This is called both on initial load of the plugin to populate with
|
||||||
This is called both on initial load of the plugin to populate with
|
existing files, and when the user adds new files via the media manager.
|
||||||
existing files, and when the user adds new files via the media manager
|
|
||||||
"""
|
"""
|
||||||
currlist = self.get_file_list()
|
current_list = self.get_file_list()
|
||||||
titles = [os.path.split(file)[1] for file in currlist]
|
titles = [os.path.split(file)[1] for file in current_list]
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
if not initialLoad:
|
if not initial_load:
|
||||||
self.main_window.display_progress_bar(len(files))
|
self.main_window.display_progress_bar(len(files))
|
||||||
# Sort the presentations by its filename considering language specific characters.
|
# Sort the presentations by its filename considering language specific characters.
|
||||||
files.sort(key=lambda filename: get_locale_key(os.path.split(unicode(filename))[1]))
|
files.sort(key=lambda filename: get_locale_key(os.path.split(unicode(filename))[1]))
|
||||||
for file in files:
|
for file in files:
|
||||||
if not initialLoad:
|
if not initial_load:
|
||||||
self.main_window.increment_progress_bar()
|
self.main_window.increment_progress_bar()
|
||||||
if currlist.count(file) > 0:
|
if current_list.count(file) > 0:
|
||||||
continue
|
continue
|
||||||
filename = os.path.split(unicode(file))[1]
|
filename = os.path.split(unicode(file))[1]
|
||||||
if not os.path.exists(file):
|
if not os.path.exists(file):
|
||||||
item_name = QtGui.QListWidgetItem(filename)
|
item_name = QtGui.QListWidgetItem(filename)
|
||||||
item_name.setIcon(build_icon(ERROR))
|
item_name.setIcon(build_icon(ERROR_IMAGE))
|
||||||
item_name.setData(QtCore.Qt.UserRole, file)
|
item_name.setData(QtCore.Qt.UserRole, file)
|
||||||
item_name.setToolTip(file)
|
item_name.setToolTip(file)
|
||||||
self.list_view.addItem(item_name)
|
self.list_view.addItem(item_name)
|
||||||
else:
|
else:
|
||||||
if titles.count(filename) > 0:
|
if titles.count(filename) > 0:
|
||||||
if not initialLoad:
|
if not initial_load:
|
||||||
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'File Exists'),
|
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'File Exists'),
|
||||||
translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem',
|
||||||
'A presentation with that filename already exists.')
|
'A presentation with that filename already exists.')
|
||||||
@ -180,7 +182,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
doc = controller.add_document(unicode(file))
|
doc = controller.add_document(unicode(file))
|
||||||
thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
|
thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
|
||||||
preview = doc.get_thumbnail_path(1, True)
|
preview = doc.get_thumbnail_path(1, True)
|
||||||
if not preview and not initialLoad:
|
if not preview and not initial_load:
|
||||||
doc.load_presentation()
|
doc.load_presentation()
|
||||||
preview = doc.get_thumbnail_path(1, True)
|
preview = doc.get_thumbnail_path(1, True)
|
||||||
doc.close_presentation()
|
doc.close_presentation()
|
||||||
@ -192,7 +194,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
else:
|
else:
|
||||||
icon = create_thumb(preview, thumb)
|
icon = create_thumb(preview, thumb)
|
||||||
else:
|
else:
|
||||||
if initialLoad:
|
if initial_load:
|
||||||
icon = build_icon(u':/general/general_delete.png')
|
icon = build_icon(u':/general/general_delete.png')
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings().UnsupportedFile,
|
critical_error_message_box(UiStrings().UnsupportedFile,
|
||||||
@ -203,13 +205,13 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
item_name.setIcon(icon)
|
item_name.setIcon(icon)
|
||||||
item_name.setToolTip(file)
|
item_name.setToolTip(file)
|
||||||
self.list_view.addItem(item_name)
|
self.list_view.addItem(item_name)
|
||||||
if not initialLoad:
|
if not initial_load:
|
||||||
self.main_window.finished_progress_bar()
|
self.main_window.finished_progress_bar()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
def on_delete_click(self):
|
def on_delete_click(self):
|
||||||
"""
|
"""
|
||||||
Remove a presentation item from the list
|
Remove a presentation item from the list.
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.list_view, UiStrings().SelectDelete):
|
if check_item_selected(self.list_view, UiStrings().SelectDelete):
|
||||||
items = self.list_view.selectedIndexes()
|
items = self.list_view.selectedIndexes()
|
||||||
@ -230,12 +232,11 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
self.list_view.takeItem(row)
|
self.list_view.takeItem(row)
|
||||||
Settings().setValue(self.settings_section + u'/presentations files', self.get_file_list())
|
Settings().setValue(self.settings_section + u'/presentations files', self.get_file_list())
|
||||||
|
|
||||||
def generate_slide_data(self, service_item, item=None, xmlVersion=False,
|
def generate_slide_data(self, service_item, item=None, xml_version=False,
|
||||||
remote=False, context=ServiceItemContext.Service):
|
remote=False, context=ServiceItemContext.Service):
|
||||||
"""
|
"""
|
||||||
Load the relevant information for displaying the presentation
|
Load the relevant information for displaying the presentation in the slidecontroller. In the case of
|
||||||
in the slidecontroller. In the case of powerpoints, an image
|
powerpoints, an image for each slide.
|
||||||
for each slide
|
|
||||||
"""
|
"""
|
||||||
if item:
|
if item:
|
||||||
items = [item]
|
items = [item]
|
||||||
@ -287,26 +288,24 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def findControllerByType(self, filename):
|
def findControllerByType(self, filename):
|
||||||
"""
|
"""
|
||||||
Determine the default application controller to use for the selected
|
Determine the default application controller to use for the selected file type. This is used if "Automatic" is
|
||||||
file type. This is used if "Automatic" is set as the preferred
|
set as the preferred controller. Find the first (alphabetic) enabled controller which "supports" the extension.
|
||||||
controller. Find the first (alphabetic) enabled controller which
|
If none found, then look for a controller which "also supports" it instead.
|
||||||
"supports" the extension. If none found, then look for a controller
|
|
||||||
which "also supports" it instead.
|
|
||||||
"""
|
"""
|
||||||
filetype = os.path.splitext(filename)[1][1:]
|
file_type = os.path.splitext(filename)[1][1:]
|
||||||
if not filetype:
|
if not file_type:
|
||||||
return None
|
return None
|
||||||
for controller in self.controllers:
|
for controller in self.controllers:
|
||||||
if self.controllers[controller].enabled():
|
if self.controllers[controller].enabled():
|
||||||
if filetype in self.controllers[controller].supports:
|
if file_type in self.controllers[controller].supports:
|
||||||
return controller
|
return controller
|
||||||
for controller in self.controllers:
|
for controller in self.controllers:
|
||||||
if self.controllers[controller].enabled():
|
if self.controllers[controller].enabled():
|
||||||
if filetype in self.controllers[controller].alsosupports:
|
if file_type in self.controllers[controller].also_supports:
|
||||||
return controller
|
return controller
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def search(self, string, showError):
|
def search(self, string, show_error):
|
||||||
files = Settings().value(self.settings_section + u'/presentations files')
|
files = Settings().value(self.settings_section + u'/presentations files')
|
||||||
results = []
|
results = []
|
||||||
string = string.lower()
|
string = string.lower()
|
||||||
|
@ -38,8 +38,8 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
"""
|
"""
|
||||||
This is the Presentation listener who acts on events from the slide
|
This is the Presentation listener who acts on events from the slide controller and passes the messages on the the
|
||||||
controller and passes the messages on the the correct presentation handlers
|
correct presentation handlers.
|
||||||
"""
|
"""
|
||||||
log.info(u'Controller loaded')
|
log.info(u'Controller loaded')
|
||||||
|
|
||||||
@ -54,9 +54,8 @@ class Controller(object):
|
|||||||
|
|
||||||
def add_handler(self, controller, file, hide_mode, slide_no):
|
def add_handler(self, controller, file, hide_mode, slide_no):
|
||||||
"""
|
"""
|
||||||
Add a handler, which is an instance of a presentation and
|
Add a handler, which is an instance of a presentation and slidecontroller combination. If the slidecontroller
|
||||||
slidecontroller combination. If the slidecontroller has a display
|
has a display then load the presentation.
|
||||||
then load the presentation.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, add_handler %s' % (self.is_live, file))
|
log.debug(u'Live = %s, add_handler %s' % (self.is_live, file))
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
@ -86,8 +85,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def activate(self):
|
def activate(self):
|
||||||
"""
|
"""
|
||||||
Active the presentation, and show it on the screen.
|
Active the presentation, and show it on the screen. Use the last slide number.
|
||||||
Use the last slide number.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, activate' % self.is_live)
|
log.debug(u'Live = %s, activate' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -130,7 +128,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def first(self):
|
def first(self):
|
||||||
"""
|
"""
|
||||||
Based on the handler passed at startup triggers the first slide
|
Based on the handler passed at startup triggers the first slide.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, first' % self.is_live)
|
log.debug(u'Live = %s, first' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -148,7 +146,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def last(self):
|
def last(self):
|
||||||
"""
|
"""
|
||||||
Based on the handler passed at startup triggers the last slide
|
Based on the handler passed at startup triggers the last slide.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, last' % self.is_live)
|
log.debug(u'Live = %s, last' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -166,7 +164,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
"""
|
"""
|
||||||
Based on the handler passed at startup triggers the next slide event
|
Based on the handler passed at startup triggers the next slide event.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, next' % self.is_live)
|
log.debug(u'Live = %s, next' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -182,9 +180,8 @@ class Controller(object):
|
|||||||
return
|
return
|
||||||
if not self.activate():
|
if not self.activate():
|
||||||
return
|
return
|
||||||
# The "End of slideshow" screen is after the last slide
|
# The "End of slideshow" screen is after the last slide. Note, we can't just stop on the last slide, since it
|
||||||
# Note, we can't just stop on the last slide, since it may
|
# may contain animations that need to be stepped through.
|
||||||
# contain animations that need to be stepped through.
|
|
||||||
if self.doc.slidenumber > self.doc.get_slide_count():
|
if self.doc.slidenumber > self.doc.get_slide_count():
|
||||||
return
|
return
|
||||||
self.doc.next_step()
|
self.doc.next_step()
|
||||||
@ -192,7 +189,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def previous(self):
|
def previous(self):
|
||||||
"""
|
"""
|
||||||
Based on the handler passed at startup triggers the previous slide event
|
Based on the handler passed at startup triggers the previous slide event.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, previous' % self.is_live)
|
log.debug(u'Live = %s, previous' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -213,7 +210,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
"""
|
"""
|
||||||
Based on the handler passed at startup triggers slide show to shut down
|
Based on the handler passed at startup triggers slide show to shut down.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, shutdown' % self.is_live)
|
log.debug(u'Live = %s, shutdown' % self.is_live)
|
||||||
if not self.doc:
|
if not self.doc:
|
||||||
@ -223,7 +220,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def blank(self, hide_mode):
|
def blank(self, hide_mode):
|
||||||
"""
|
"""
|
||||||
Instruct the controller to blank the presentation
|
Instruct the controller to blank the presentation.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, blank' % self.is_live)
|
log.debug(u'Live = %s, blank' % self.is_live)
|
||||||
self.hide_mode = hide_mode
|
self.hide_mode = hide_mode
|
||||||
@ -244,7 +241,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Instruct the controller to stop and hide the presentation
|
Instruct the controller to stop and hide the presentation.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, stop' % self.is_live)
|
log.debug(u'Live = %s, stop' % self.is_live)
|
||||||
self.hide_mode = HideMode.Screen
|
self.hide_mode = HideMode.Screen
|
||||||
@ -260,7 +257,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def unblank(self):
|
def unblank(self):
|
||||||
"""
|
"""
|
||||||
Instruct the controller to unblank the presentation
|
Instruct the controller to unblank the presentation.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Live = %s, unblank' % self.is_live)
|
log.debug(u'Live = %s, unblank' % self.is_live)
|
||||||
self.hide_mode = None
|
self.hide_mode = None
|
||||||
@ -283,8 +280,8 @@ class Controller(object):
|
|||||||
|
|
||||||
class MessageListener(object):
|
class MessageListener(object):
|
||||||
"""
|
"""
|
||||||
This is the Presentation listener who acts on events from the slide
|
This is the Presentation listener who acts on events from the slide controller and passes the messages on the the
|
||||||
controller and passes the messages on the the correct presentation handlers
|
correct presentation handlers
|
||||||
"""
|
"""
|
||||||
log.info(u'Message Listener loaded')
|
log.info(u'Message Listener loaded')
|
||||||
|
|
||||||
@ -310,12 +307,11 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def startup(self, message):
|
def startup(self, message):
|
||||||
"""
|
"""
|
||||||
Start of new presentation
|
Start of new presentation. Save the handler as any new presentations start here
|
||||||
Save the handler as any new presentations start here
|
|
||||||
"""
|
"""
|
||||||
|
log.debug(u'Startup called with message %s' % message)
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
item = message[0]
|
item = message[0]
|
||||||
log.debug(u'Startup called with message %s' % message)
|
|
||||||
hide_mode = message[2]
|
hide_mode = message[2]
|
||||||
file = item.get_frame_path()
|
file = item.get_frame_path()
|
||||||
self.handler = item.title
|
self.handler = item.title
|
||||||
@ -331,7 +327,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def slide(self, message):
|
def slide(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to move to a specific slide
|
React to the message to move to a specific slide.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
slide = message[2]
|
slide = message[2]
|
||||||
@ -342,7 +338,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def first(self, message):
|
def first(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to move to the first slide
|
React to the message to move to the first slide.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -352,7 +348,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def last(self, message):
|
def last(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to move to the last slide
|
React to the message to move to the last slide.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -362,7 +358,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def next(self, message):
|
def next(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to move to the next animation/slide
|
React to the message to move to the next animation/slide.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -372,7 +368,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def previous(self, message):
|
def previous(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to move to the previous animation/slide
|
React to the message to move to the previous animation/slide.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -382,8 +378,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def shutdown(self, message):
|
def shutdown(self, message):
|
||||||
"""
|
"""
|
||||||
React to message to shutdown the presentation. I.e. end the show
|
React to message to shutdown the presentation. I.e. end the show and close the file.
|
||||||
and close the file
|
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -393,7 +388,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def hide(self, message):
|
def hide(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to show the desktop
|
React to the message to show the desktop.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -401,7 +396,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def blank(self, message):
|
def blank(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to blank the display
|
React to the message to blank the display.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
hide_mode = message[2]
|
hide_mode = message[2]
|
||||||
@ -410,7 +405,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def unblank(self, message):
|
def unblank(self, message):
|
||||||
"""
|
"""
|
||||||
React to the message to unblank the display
|
React to the message to unblank the display.
|
||||||
"""
|
"""
|
||||||
is_live = message[1]
|
is_live = message[1]
|
||||||
if is_live:
|
if is_live:
|
||||||
@ -418,9 +413,7 @@ class MessageListener(object):
|
|||||||
|
|
||||||
def timeout(self):
|
def timeout(self):
|
||||||
"""
|
"""
|
||||||
The presentation may be timed or might be controlled by the
|
The presentation may be timed or might be controlled by the application directly, rather than through OpenLP.
|
||||||
application directly, rather than through OpenLP. Poll occasionally
|
Poll occasionally to check which slide is currently displayed so the slidecontroller view can be updated.
|
||||||
to check which slide is currently displayed so the slidecontroller
|
|
||||||
view can be updated
|
|
||||||
"""
|
"""
|
||||||
self.live_handler.poll()
|
self.live_handler.poll()
|
||||||
|
@ -26,7 +26,10 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
This modul is for controlling powerpiont. PPT API documentation:
|
||||||
|
`http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx`_
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -39,16 +42,14 @@ if os.name == u'nt':
|
|||||||
from openlp.core.lib import ScreenList
|
from openlp.core.lib import ScreenList
|
||||||
from presentationcontroller import PresentationController, PresentationDocument
|
from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# PPT API documentation:
|
|
||||||
# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
|
|
||||||
|
|
||||||
class PowerpointController(PresentationController):
|
class PowerpointController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with PowerPoint Presentations
|
Class to control interactions with PowerPoint Presentations. It creates the runtime Environment , Loads the and
|
||||||
It creates the runtime Environment , Loads the and Closes the Presentation
|
Closes the Presentation. As well as triggering the correct activities based on the users input.
|
||||||
As well as triggering the correct activities based on the users input
|
|
||||||
"""
|
"""
|
||||||
log.info(u'PowerpointController loaded')
|
log.info(u'PowerpointController loaded')
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ class PowerpointController(PresentationController):
|
|||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
PowerPoint is able to run on this machine
|
PowerPoint is able to run on this machine.
|
||||||
"""
|
"""
|
||||||
log.debug(u'check_available')
|
log.debug(u'check_available')
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
@ -77,7 +78,7 @@ class PowerpointController(PresentationController):
|
|||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
def start_process(self):
|
def start_process(self):
|
||||||
"""
|
"""
|
||||||
Loads PowerPoint process
|
Loads PowerPoint process.
|
||||||
"""
|
"""
|
||||||
log.debug(u'start_process')
|
log.debug(u'start_process')
|
||||||
if not self.process:
|
if not self.process:
|
||||||
@ -87,7 +88,7 @@ class PowerpointController(PresentationController):
|
|||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
"""
|
"""
|
||||||
Called at system exit to clean up any running presentations
|
Called at system exit to clean up any running presentations.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Kill powerpoint')
|
log.debug(u'Kill powerpoint')
|
||||||
while self.docs:
|
while self.docs:
|
||||||
@ -105,12 +106,12 @@ class PowerpointController(PresentationController):
|
|||||||
|
|
||||||
class PowerpointDocument(PresentationDocument):
|
class PowerpointDocument(PresentationDocument):
|
||||||
"""
|
"""
|
||||||
Class which holds information and controls a single presentation
|
Class which holds information and controls a single presentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, controller, presentation):
|
def __init__(self, controller, presentation):
|
||||||
"""
|
"""
|
||||||
Constructor, store information about the file and initialise
|
Constructor, store information about the file and initialise.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Init Presentation Powerpoint')
|
log.debug(u'Init Presentation Powerpoint')
|
||||||
PresentationDocument.__init__(self, controller, presentation)
|
PresentationDocument.__init__(self, controller, presentation)
|
||||||
@ -118,8 +119,8 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
|
|
||||||
def load_presentation(self):
|
def load_presentation(self):
|
||||||
"""
|
"""
|
||||||
Called when a presentation is added to the SlideController.
|
Called when a presentation is added to the SlideController. Opens the PowerPoint file using the process created
|
||||||
Opens the PowerPoint file using the process created earlier.
|
earlier.
|
||||||
"""
|
"""
|
||||||
log.debug(u'load_presentation')
|
log.debug(u'load_presentation')
|
||||||
if not self.controller.process or not self.controller.process.Visible:
|
if not self.controller.process or not self.controller.process.Visible:
|
||||||
@ -142,20 +143,19 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
self.presentation.Slides[n].Copy()
|
self.presentation.Slides[n].Copy()
|
||||||
thumbnail = QApplication.clipboard.image()
|
thumbnail = QApplication.clipboard.image()
|
||||||
|
|
||||||
However, for the moment, we want a physical file since it makes life
|
However, for the moment, we want a physical file since it makes life easier elsewhere.
|
||||||
easier elsewhere.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'create_thumbnails')
|
log.debug(u'create_thumbnails')
|
||||||
if self.check_thumbnails():
|
if self.check_thumbnails():
|
||||||
return
|
return
|
||||||
for num in range(self.presentation.Slides.Count):
|
for num in range(self.presentation.Slides.Count):
|
||||||
self.presentation.Slides(num + 1).Export(os.path.join(
|
self.presentation.Slides(num + 1).Export(
|
||||||
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)), 'png', 320, 240)
|
os.path.join(self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)), 'png', 320, 240)
|
||||||
|
|
||||||
def close_presentation(self):
|
def close_presentation(self):
|
||||||
"""
|
"""
|
||||||
Close presentation and clean up objects. This is triggered by a new
|
Close presentation and clean up objects. This is triggered by a new object being added to SlideController or
|
||||||
object being added to SlideController or OpenLP being shut down.
|
OpenLP being shut down.
|
||||||
"""
|
"""
|
||||||
log.debug(u'ClosePresentation')
|
log.debug(u'ClosePresentation')
|
||||||
if self.presentation:
|
if self.presentation:
|
||||||
@ -182,7 +182,6 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
"""
|
"""
|
||||||
Returns ``True`` if a presentation is currently active.
|
Returns ``True`` if a presentation is currently active.
|
||||||
@ -253,15 +252,14 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
dpi = win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
|
dpi = win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
|
||||||
except win32ui.error:
|
except win32ui.error:
|
||||||
dpi = 96
|
dpi = 96
|
||||||
rect = ScreenList().current[u'size']
|
size = ScreenList().current[u'size']
|
||||||
ppt_window = self.presentation.SlideShowSettings.Run()
|
ppt_window = self.presentation.SlideShowSettings.Run()
|
||||||
if not ppt_window:
|
if not ppt_window:
|
||||||
return
|
return
|
||||||
ppt_window.Top = rect.y() * 72 / dpi
|
ppt_window.Top = size.y() * 72 / dpi
|
||||||
ppt_window.Height = rect.height() * 72 / dpi
|
ppt_window.Height = size.height() * 72 / dpi
|
||||||
ppt_window.Left = rect.x() * 72 / dpi
|
ppt_window.Left = size.x() * 72 / dpi
|
||||||
ppt_window.Width = rect.width() * 72 / dpi
|
ppt_window.Width = size.width() * 72 / dpi
|
||||||
|
|
||||||
|
|
||||||
def get_slide_number(self):
|
def get_slide_number(self):
|
||||||
"""
|
"""
|
||||||
@ -318,6 +316,7 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
"""
|
"""
|
||||||
return _get_text_from_shapes(self.presentation.Slides(slide_no).NotesPage.Shapes)
|
return _get_text_from_shapes(self.presentation.Slides(slide_no).NotesPage.Shapes)
|
||||||
|
|
||||||
|
|
||||||
def _get_text_from_shapes(shapes):
|
def _get_text_from_shapes(shapes):
|
||||||
"""
|
"""
|
||||||
Returns any text extracted from the shapes on a presentation slide.
|
Returns any text extracted from the shapes on a presentation slide.
|
||||||
@ -326,8 +325,8 @@ def _get_text_from_shapes(shapes):
|
|||||||
A set of shapes to search for text.
|
A set of shapes to search for text.
|
||||||
"""
|
"""
|
||||||
text = ''
|
text = ''
|
||||||
for idx in range(shapes.Count):
|
for index in range(shapes.Count):
|
||||||
shape = shapes(idx + 1)
|
shape = shapes(index + 1)
|
||||||
if shape.HasTextFrame:
|
if shape.HasTextFrame:
|
||||||
text += shape.TextFrame.TextRange.Text + '\n'
|
text += shape.TextFrame.TextRange.Text + '\n'
|
||||||
return text
|
return text
|
||||||
|
@ -37,13 +37,14 @@ if os.name == u'nt':
|
|||||||
from openlp.core.lib import ScreenList
|
from openlp.core.lib import ScreenList
|
||||||
from presentationcontroller import PresentationController, PresentationDocument
|
from presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PptviewController(PresentationController):
|
class PptviewController(PresentationController):
|
||||||
"""
|
"""
|
||||||
Class to control interactions with PowerPoint Viewer Presentations
|
Class to control interactions with PowerPoint Viewer Presentations. It creates the runtime Environment , Loads the
|
||||||
It creates the runtime Environment , Loads the and Closes the Presentation
|
and Closes the Presentation. As well as triggering the correct activities based on the users input
|
||||||
As well as triggering the correct activities based on the users input
|
|
||||||
"""
|
"""
|
||||||
log.info(u'PPTViewController loaded')
|
log.info(u'PPTViewController loaded')
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ class PptviewController(PresentationController):
|
|||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
PPT Viewer is able to run on this machine
|
PPT Viewer is able to run on this machine.
|
||||||
"""
|
"""
|
||||||
log.debug(u'check_available')
|
log.debug(u'check_available')
|
||||||
if os.name != u'nt':
|
if os.name != u'nt':
|
||||||
@ -68,7 +69,7 @@ class PptviewController(PresentationController):
|
|||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
def check_installed(self):
|
def check_installed(self):
|
||||||
"""
|
"""
|
||||||
Check the viewer is installed
|
Check the viewer is installed.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Check installed')
|
log.debug(u'Check installed')
|
||||||
try:
|
try:
|
||||||
@ -79,14 +80,14 @@ class PptviewController(PresentationController):
|
|||||||
|
|
||||||
def start_process(self):
|
def start_process(self):
|
||||||
"""
|
"""
|
||||||
Loads the PPTVIEWLIB library
|
Loads the PPTVIEWLIB library.
|
||||||
"""
|
"""
|
||||||
if self.process:
|
if self.process:
|
||||||
return
|
return
|
||||||
log.debug(u'start PPTView')
|
log.debug(u'start PPTView')
|
||||||
dllpath = os.path.join(self.plugin_manager.base_path, u'presentations', u'lib', u'pptviewlib',
|
dll_path = os.path.join(
|
||||||
u'pptviewlib.dll')
|
self.plugin_manager.base_path, u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll')
|
||||||
self.process = cdll.LoadLibrary(dllpath)
|
self.process = cdll.LoadLibrary(dll_path)
|
||||||
if log.isEnabledFor(logging.DEBUG):
|
if log.isEnabledFor(logging.DEBUG):
|
||||||
self.process.SetDebug(1)
|
self.process.SetDebug(1)
|
||||||
|
|
||||||
@ -101,33 +102,32 @@ class PptviewController(PresentationController):
|
|||||||
|
|
||||||
class PptviewDocument(PresentationDocument):
|
class PptviewDocument(PresentationDocument):
|
||||||
"""
|
"""
|
||||||
Class which holds information and controls a single presentation
|
Class which holds information and controls a single presentation.
|
||||||
"""
|
"""
|
||||||
def __init__(self, controller, presentation):
|
def __init__(self, controller, presentation):
|
||||||
"""
|
"""
|
||||||
Constructor, store information about the file and initialise
|
Constructor, store information about the file and initialise.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Init Presentation PowerPoint')
|
log.debug(u'Init Presentation PowerPoint')
|
||||||
PresentationDocument.__init__(self, controller, presentation)
|
PresentationDocument.__init__(self, controller, presentation)
|
||||||
self.presentation = None
|
self.presentation = None
|
||||||
self.pptid = None
|
self.ppt_id = None
|
||||||
self.blanked = False
|
self.blanked = False
|
||||||
self.hidden = False
|
self.hidden = False
|
||||||
|
|
||||||
def load_presentation(self):
|
def load_presentation(self):
|
||||||
"""
|
"""
|
||||||
Called when a presentation is added to the SlideController.
|
Called when a presentation is added to the SlideController. It builds the environment, starts communication with
|
||||||
It builds the environment, starts communication with the background
|
the background PptView task started earlier.
|
||||||
PptView task started earlier.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'LoadPresentation')
|
log.debug(u'LoadPresentation')
|
||||||
rect = ScreenList().current[u'size']
|
size = ScreenList().current[u'size']
|
||||||
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
|
rect = RECT(size.x(), size.y(), size.right(), size.bottom())
|
||||||
filepath = str(self.filepath.replace(u'/', u'\\'))
|
filepath = str(self.filepath.replace(u'/', u'\\'))
|
||||||
if not os.path.isdir(self.get_temp_folder()):
|
if not os.path.isdir(self.get_temp_folder()):
|
||||||
os.makedirs(self.get_temp_folder())
|
os.makedirs(self.get_temp_folder())
|
||||||
self.pptid = self.controller.process.OpenPPT(filepath, None, rect, str(self.get_temp_folder()) + '\\slide')
|
self.ppt_id = self.controller.process.OpenPPT(filepath, None, rect, str(self.get_temp_folder()) + '\\slide')
|
||||||
if self.pptid >= 0:
|
if self.ppt_id >= 0:
|
||||||
self.create_thumbnails()
|
self.create_thumbnails()
|
||||||
self.stop_presentation()
|
self.stop_presentation()
|
||||||
return True
|
return True
|
||||||
@ -136,8 +136,7 @@ class PptviewDocument(PresentationDocument):
|
|||||||
|
|
||||||
def create_thumbnails(self):
|
def create_thumbnails(self):
|
||||||
"""
|
"""
|
||||||
PPTviewLib creates large BMP's, but we want small PNG's for consistency.
|
PPTviewLib creates large BMP's, but we want small PNG's for consistency. Convert them here.
|
||||||
Convert them here.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'create_thumbnails')
|
log.debug(u'create_thumbnails')
|
||||||
if self.check_thumbnails():
|
if self.check_thumbnails():
|
||||||
@ -149,21 +148,20 @@ class PptviewDocument(PresentationDocument):
|
|||||||
|
|
||||||
def close_presentation(self):
|
def close_presentation(self):
|
||||||
"""
|
"""
|
||||||
Close presentation and clean up objects
|
Close presentation and clean up objects. Triggered by new object being added to SlideController or OpenLP being
|
||||||
Triggered by new object being added to SlideController orOpenLP
|
shut down.
|
||||||
being shut down
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'ClosePresentation')
|
log.debug(u'ClosePresentation')
|
||||||
if self.controller.process:
|
if self.controller.process:
|
||||||
self.controller.process.ClosePPT(self.pptid)
|
self.controller.process.ClosePPT(self.ppt_id)
|
||||||
self.pptid = -1
|
self.ppt_id = -1
|
||||||
self.controller.remove_doc(self)
|
self.controller.remove_doc(self)
|
||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
"""
|
"""
|
||||||
Returns true if a presentation is loaded
|
Returns true if a presentation is loaded.
|
||||||
"""
|
"""
|
||||||
if self.pptid < 0:
|
if self.ppt_id < 0:
|
||||||
return False
|
return False
|
||||||
if self.get_slide_count() < 0:
|
if self.get_slide_count() < 0:
|
||||||
return False
|
return False
|
||||||
@ -171,74 +169,74 @@ class PptviewDocument(PresentationDocument):
|
|||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
"""
|
"""
|
||||||
Returns true if a presentation is currently active
|
Returns true if a presentation is currently active.
|
||||||
"""
|
"""
|
||||||
return self.is_loaded() and not self.hidden
|
return self.is_loaded() and not self.hidden
|
||||||
|
|
||||||
def blank_screen(self):
|
def blank_screen(self):
|
||||||
"""
|
"""
|
||||||
Blanks the screen
|
Blanks the screen.
|
||||||
"""
|
"""
|
||||||
self.controller.process.Blank(self.pptid)
|
self.controller.process.Blank(self.ppt_id)
|
||||||
self.blanked = True
|
self.blanked = True
|
||||||
|
|
||||||
def unblank_screen(self):
|
def unblank_screen(self):
|
||||||
"""
|
"""
|
||||||
Unblanks (restores) the presentation
|
Unblanks (restores) the presentation.
|
||||||
"""
|
"""
|
||||||
self.controller.process.Unblank(self.pptid)
|
self.controller.process.Unblank(self.ppt_id)
|
||||||
self.blanked = False
|
self.blanked = False
|
||||||
|
|
||||||
def is_blank(self):
|
def is_blank(self):
|
||||||
"""
|
"""
|
||||||
Returns true if screen is blank
|
Returns true if screen is blank.
|
||||||
"""
|
"""
|
||||||
log.debug(u'is blank OpenOffice')
|
log.debug(u'is blank OpenOffice')
|
||||||
return self.blanked
|
return self.blanked
|
||||||
|
|
||||||
def stop_presentation(self):
|
def stop_presentation(self):
|
||||||
"""
|
"""
|
||||||
Stops the current presentation and hides the output
|
Stops the current presentation and hides the output.
|
||||||
"""
|
"""
|
||||||
self.hidden = True
|
self.hidden = True
|
||||||
self.controller.process.Stop(self.pptid)
|
self.controller.process.Stop(self.ppt_id)
|
||||||
|
|
||||||
def start_presentation(self):
|
def start_presentation(self):
|
||||||
"""
|
"""
|
||||||
Starts a presentation from the beginning
|
Starts a presentation from the beginning.
|
||||||
"""
|
"""
|
||||||
if self.hidden:
|
if self.hidden:
|
||||||
self.hidden = False
|
self.hidden = False
|
||||||
self.controller.process.Resume(self.pptid)
|
self.controller.process.Resume(self.ppt_id)
|
||||||
else:
|
else:
|
||||||
self.controller.process.RestartShow(self.pptid)
|
self.controller.process.RestartShow(self.ppt_id)
|
||||||
|
|
||||||
def get_slide_number(self):
|
def get_slide_number(self):
|
||||||
"""
|
"""
|
||||||
Returns the current slide number
|
Returns the current slide number.
|
||||||
"""
|
"""
|
||||||
return self.controller.process.GetCurrentSlide(self.pptid)
|
return self.controller.process.GetCurrentSlide(self.ppt_id)
|
||||||
|
|
||||||
def get_slide_count(self):
|
def get_slide_count(self):
|
||||||
"""
|
"""
|
||||||
Returns total number of slides
|
Returns total number of slides.
|
||||||
"""
|
"""
|
||||||
return self.controller.process.GetSlideCount(self.pptid)
|
return self.controller.process.GetSlideCount(self.ppt_id)
|
||||||
|
|
||||||
def goto_slide(self, slideno):
|
def goto_slide(self, slideno):
|
||||||
"""
|
"""
|
||||||
Moves to a specific slide in the presentation
|
Moves to a specific slide in the presentation.
|
||||||
"""
|
"""
|
||||||
self.controller.process.GotoSlide(self.pptid, slideno)
|
self.controller.process.GotoSlide(self.ppt_id, slideno)
|
||||||
|
|
||||||
def next_step(self):
|
def next_step(self):
|
||||||
"""
|
"""
|
||||||
Triggers the next effect of slide on the running presentation
|
Triggers the next effect of slide on the running presentation.
|
||||||
"""
|
"""
|
||||||
self.controller.process.NextStep(self.pptid)
|
self.controller.process.NextStep(self.ppt_id)
|
||||||
|
|
||||||
def previous_step(self):
|
def previous_step(self):
|
||||||
"""
|
"""
|
||||||
Triggers the previous slide on the running presentation
|
Triggers the previous slide on the running presentation.
|
||||||
"""
|
"""
|
||||||
self.controller.process.PrevStep(self.pptid)
|
self.controller.process.PrevStep(self.ppt_id)
|
||||||
|
@ -40,9 +40,8 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class PresentationDocument(object):
|
class PresentationDocument(object):
|
||||||
"""
|
"""
|
||||||
Base class for presentation documents to inherit from.
|
Base class for presentation documents to inherit from. Loads and closes the presentation as well as triggering the
|
||||||
Loads and closes the presentation as well as triggering the correct
|
correct activities based on the users input
|
||||||
activities based on the users input
|
|
||||||
|
|
||||||
**Hook Functions**
|
**Hook Functions**
|
||||||
|
|
||||||
@ -131,20 +130,17 @@ class PresentationDocument(object):
|
|||||||
"""
|
"""
|
||||||
The location where thumbnail images will be stored
|
The location where thumbnail images will be stored
|
||||||
"""
|
"""
|
||||||
return os.path.join(
|
return os.path.join(self.controller.thumbnail_folder, self.get_file_name())
|
||||||
self.controller.thumbnail_folder, self.get_file_name())
|
|
||||||
|
|
||||||
def get_temp_folder(self):
|
def get_temp_folder(self):
|
||||||
"""
|
"""
|
||||||
The location where thumbnail images will be stored
|
The location where thumbnail images will be stored
|
||||||
"""
|
"""
|
||||||
return os.path.join(
|
return os.path.join(self.controller.temp_folder, self.get_file_name())
|
||||||
self.controller.temp_folder, self.get_file_name())
|
|
||||||
|
|
||||||
def check_thumbnails(self):
|
def check_thumbnails(self):
|
||||||
"""
|
"""
|
||||||
Returns ``True`` if the thumbnail images exist and are more recent than
|
Returns ``True`` if the thumbnail images exist and are more recent than the powerpoint file.
|
||||||
the powerpoint file.
|
|
||||||
"""
|
"""
|
||||||
lastimage = self.get_thumbnail_path(self.get_slide_count(), True)
|
lastimage = self.get_thumbnail_path(self.get_slide_count(), True)
|
||||||
if not (lastimage and os.path.isfile(lastimage)):
|
if not (lastimage and os.path.isfile(lastimage)):
|
||||||
@ -153,8 +149,7 @@ class PresentationDocument(object):
|
|||||||
|
|
||||||
def close_presentation(self):
|
def close_presentation(self):
|
||||||
"""
|
"""
|
||||||
Close presentation and clean up objects
|
Close presentation and clean up objects. Triggered by new object being added to SlideController
|
||||||
Triggered by new object being added to SlideController
|
|
||||||
"""
|
"""
|
||||||
self.controller.close_presentation()
|
self.controller.close_presentation()
|
||||||
|
|
||||||
@ -223,8 +218,8 @@ class PresentationDocument(object):
|
|||||||
|
|
||||||
def next_step(self):
|
def next_step(self):
|
||||||
"""
|
"""
|
||||||
Triggers the next effect of slide on the running presentation
|
Triggers the next effect of slide on the running presentation. This might be the next animation on the current
|
||||||
This might be the next animation on the current slide, or the next slide
|
slide, or the next slide
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -236,8 +231,7 @@ class PresentationDocument(object):
|
|||||||
|
|
||||||
def convert_thumbnail(self, file, idx):
|
def convert_thumbnail(self, file, idx):
|
||||||
"""
|
"""
|
||||||
Convert the slide image the application made to a standard 320x240
|
Convert the slide image the application made to a standard 320x240 .png image.
|
||||||
.png image.
|
|
||||||
"""
|
"""
|
||||||
if self.check_thumbnails():
|
if self.check_thumbnails():
|
||||||
return
|
return
|
||||||
@ -281,7 +275,7 @@ class PresentationDocument(object):
|
|||||||
Returns the text on the slide
|
Returns the text on the slide
|
||||||
|
|
||||||
``slide_no``
|
``slide_no``
|
||||||
The slide the text is required for, starting at 1
|
The slide the text is required for, starting at 1
|
||||||
"""
|
"""
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@ -290,24 +284,21 @@ class PresentationDocument(object):
|
|||||||
Returns the text on the slide
|
Returns the text on the slide
|
||||||
|
|
||||||
``slide_no``
|
``slide_no``
|
||||||
The slide the notes are required for, starting at 1
|
The slide the notes are required for, starting at 1
|
||||||
"""
|
"""
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class PresentationController(object):
|
class PresentationController(object):
|
||||||
"""
|
"""
|
||||||
This class is used to control interactions with presentation applications
|
This class is used to control interactions with presentation applications by creating a runtime environment. This is
|
||||||
by creating a runtime environment. This is a base class for presentation
|
a base class for presentation controllers to inherit from.
|
||||||
controllers to inherit from.
|
|
||||||
|
|
||||||
To create a new controller, take a copy of this file and name it so it ends
|
To create a new controller, take a copy of this file and name it so it ends with ``controller.py``, i.e.
|
||||||
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
|
``foobarcontroller.py``. Make sure it inherits
|
||||||
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
|
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`, and then fill in the
|
||||||
and then fill in the blanks. If possible try to make sure it loads on all
|
blanks. If possible try to make sure it loads on all platforms, usually by using :mod:``os.name`` checks, although
|
||||||
platforms, usually by using :mod:``os.name`` checks, although
|
``__init__``, ``check_available`` and ``presentation_deleted`` should always be implemented.
|
||||||
``__init__``, ``check_available`` and ``presentation_deleted`` should
|
|
||||||
always be implemented.
|
|
||||||
|
|
||||||
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
|
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
|
||||||
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
|
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
|
||||||
@ -317,36 +308,34 @@ class PresentationController(object):
|
|||||||
**Basic Attributes**
|
**Basic Attributes**
|
||||||
|
|
||||||
``name``
|
``name``
|
||||||
The name that appears in the options and the media manager
|
The name that appears in the options and the media manager.
|
||||||
|
|
||||||
``enabled``
|
``enabled``
|
||||||
The controller is enabled
|
The controller is enabled.
|
||||||
|
|
||||||
``available``
|
``available``
|
||||||
The controller is available on this machine. Set by init via
|
The controller is available on this machine. Set by init via call to check_available.
|
||||||
call to check_available
|
|
||||||
|
|
||||||
``plugin``
|
``plugin``
|
||||||
The presentationplugin object
|
The presentationplugin object.
|
||||||
|
|
||||||
``supports``
|
``supports``
|
||||||
The primary native file types this application supports
|
The primary native file types this application supports.
|
||||||
|
|
||||||
``alsosupports``
|
``alsosupports``
|
||||||
Other file types the application can import, although not necessarily
|
Other file types the application can import, although not necessarily the first choice due to potential
|
||||||
the first choice due to potential incompatibilities
|
incompatibilities.
|
||||||
|
|
||||||
**Hook Functions**
|
**Hook Functions**
|
||||||
|
|
||||||
``kill()``
|
``kill()``
|
||||||
Called at system exit to clean up any running presentations
|
Called at system exit to clean up any running presentations.
|
||||||
|
|
||||||
``check_available()``
|
``check_available()``
|
||||||
Returns True if presentation application is installed/can run on this
|
Returns True if presentation application is installed/can run on this machine.
|
||||||
machine
|
|
||||||
|
|
||||||
``presentation_deleted()``
|
``presentation_deleted()``
|
||||||
Deletes presentation specific files, e.g. thumbnails
|
Deletes presentation specific files, e.g. thumbnails.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
log.info(u'PresentationController loaded')
|
log.info(u'PresentationController loaded')
|
||||||
@ -354,9 +343,8 @@ class PresentationController(object):
|
|||||||
def __init__(self, plugin=None, name=u'PresentationController',
|
def __init__(self, plugin=None, name=u'PresentationController',
|
||||||
document_class=PresentationDocument):
|
document_class=PresentationDocument):
|
||||||
"""
|
"""
|
||||||
This is the constructor for the presentationcontroller object. This
|
This is the constructor for the presentationcontroller object. This provides an easy way for descendent plugins
|
||||||
provides an easy way for descendent plugins to populate common data.
|
to populate common data. This method *must* be overridden, like so::
|
||||||
This method *must* be overridden, like so::
|
|
||||||
|
|
||||||
class MyPresentationController(PresentationController):
|
class MyPresentationController(PresentationController):
|
||||||
def __init__(self, plugin):
|
def __init__(self, plugin):
|
||||||
@ -399,28 +387,26 @@ class PresentationController(object):
|
|||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
"""
|
"""
|
||||||
Presentation app is able to run on this machine
|
Presentation app is able to run on this machine.
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def start_process(self):
|
def start_process(self):
|
||||||
"""
|
"""
|
||||||
Loads a running version of the presentation application in the
|
Loads a running version of the presentation application in the background.
|
||||||
background.
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
"""
|
"""
|
||||||
Called at system exit to clean up any running presentations and
|
Called at system exit to clean up any running presentations and close the application.
|
||||||
close the application
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'Kill')
|
log.debug(u'Kill')
|
||||||
self.close_presentation()
|
self.close_presentation()
|
||||||
|
|
||||||
def add_document(self, name):
|
def add_document(self, name):
|
||||||
"""
|
"""
|
||||||
Called when a new presentation document is opened
|
Called when a new presentation document is opened.
|
||||||
"""
|
"""
|
||||||
document = self.document_class(self, name)
|
document = self.document_class(self, name)
|
||||||
self.docs.append(document)
|
self.docs.append(document)
|
||||||
@ -428,7 +414,7 @@ class PresentationController(object):
|
|||||||
|
|
||||||
def remove_doc(self, doc=None):
|
def remove_doc(self, doc=None):
|
||||||
"""
|
"""
|
||||||
Called to remove an open document from the collection
|
Called to remove an open document from the collection.
|
||||||
"""
|
"""
|
||||||
log.debug(u'remove_doc Presentation')
|
log.debug(u'remove_doc Presentation')
|
||||||
if doc is None:
|
if doc is None:
|
||||||
|
@ -91,8 +91,7 @@ class PresentationTab(SettingsTab):
|
|||||||
if checkbox.isEnabled():
|
if checkbox.isEnabled():
|
||||||
checkbox.setText(controller.name)
|
checkbox.setText(controller.name)
|
||||||
else:
|
else:
|
||||||
checkbox.setText(
|
checkbox.setText(translate('PresentationPlugin.PresentationTab', '%s (unavailable)') % controller.name)
|
||||||
translate('PresentationPlugin.PresentationTab', '%s (unavailable)') % controller.name)
|
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
"""
|
"""
|
||||||
@ -106,8 +105,8 @@ class PresentationTab(SettingsTab):
|
|||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
Save the settings. If the tab hasn't been made visible to the user then there is nothing to do,
|
Save the settings. If the tab hasn't been made visible to the user then there is nothing to do, so exit. This
|
||||||
so exit. This removes the need to start presentation applications unnecessarily.
|
removes the need to start presentation applications unnecessarily.
|
||||||
"""
|
"""
|
||||||
if not self.activated:
|
if not self.activated:
|
||||||
return
|
return
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`presentationplugin` module provides the ability for OpenLP to display
|
The :mod:`presentationplugin` module provides the ability for OpenLP to display presentations from a variety of document
|
||||||
presentations from a variety of document formats.
|
formats.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
@ -39,22 +39,23 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
|||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.presentations.lib import PresentationController, PresentationMediaItem, PresentationTab
|
from openlp.plugins.presentations.lib import PresentationController, PresentationMediaItem, PresentationTab
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
__default_settings__ = {
|
__default_settings__ = {
|
||||||
u'presentations/override app': QtCore.Qt.Unchecked,
|
u'presentations/override app': QtCore.Qt.Unchecked,
|
||||||
u'presentations/Impress': QtCore.Qt.Checked,
|
u'presentations/Impress': QtCore.Qt.Checked,
|
||||||
u'presentations/Powerpoint': QtCore.Qt.Checked,
|
u'presentations/Powerpoint': QtCore.Qt.Checked,
|
||||||
u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
u'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
||||||
u'presentations/presentations files': []
|
u'presentations/presentations files': []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PresentationPlugin(Plugin):
|
class PresentationPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
This plugin allowed a Presentation to be opened, controlled and displayed
|
This plugin allowed a Presentation to be opened, controlled and displayed on the output display. The plugin controls
|
||||||
on the output display. The plugin controls third party applications such
|
third party applications such as OpenOffice.org Impress, Microsoft PowerPoint and the PowerPoint viewer.
|
||||||
as OpenOffice.org Impress, Microsoft PowerPoint and the PowerPoint viewer
|
|
||||||
"""
|
"""
|
||||||
log = logging.getLogger(u'PresentationPlugin')
|
log = logging.getLogger(u'PresentationPlugin')
|
||||||
|
|
||||||
@ -71,16 +72,14 @@ class PresentationPlugin(Plugin):
|
|||||||
|
|
||||||
def create_settings_tab(self, parent):
|
def create_settings_tab(self, parent):
|
||||||
"""
|
"""
|
||||||
Create the settings Tab
|
Create the settings Tab.
|
||||||
"""
|
"""
|
||||||
visible_name = self.get_string(StringContent.VisibleName)
|
visible_name = self.get_string(StringContent.VisibleName)
|
||||||
self.settings_tab = PresentationTab(parent, self.name, visible_name[u'title'], self.controllers,
|
self.settings_tab = PresentationTab(parent, self.name, visible_name[u'title'], self.controllers, self.icon_path)
|
||||||
self.icon_path)
|
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
"""
|
"""
|
||||||
Initialise the plugin. Determine which controllers are enabled
|
Initialise the plugin. Determine which controllers are enabled are start their processes.
|
||||||
are start their processes.
|
|
||||||
"""
|
"""
|
||||||
log.info(u'Presentations Initialising')
|
log.info(u'Presentations Initialising')
|
||||||
Plugin.initialise(self)
|
Plugin.initialise(self)
|
||||||
@ -95,8 +94,8 @@ class PresentationPlugin(Plugin):
|
|||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
"""
|
"""
|
||||||
Finalise the plugin. Ask all the enabled presentation applications
|
Finalise the plugin. Ask all the enabled presentation applications to close down their applications and release
|
||||||
to close down their applications and release resources.
|
resources.
|
||||||
"""
|
"""
|
||||||
log.info(u'Plugin Finalise')
|
log.info(u'Plugin Finalise')
|
||||||
# Ask each controller to tidy up.
|
# Ask each controller to tidy up.
|
||||||
@ -108,26 +107,23 @@ class PresentationPlugin(Plugin):
|
|||||||
|
|
||||||
def create_media_manager_item(self):
|
def create_media_manager_item(self):
|
||||||
"""
|
"""
|
||||||
Create the Media Manager List
|
Create the Media Manager List.
|
||||||
"""
|
"""
|
||||||
self.media_item = PresentationMediaItem(
|
self.media_item = PresentationMediaItem(
|
||||||
self.main_window.media_dock_manager.media_dock, self, self.icon, self.controllers)
|
self.main_window.media_dock_manager.media_dock, self, self.icon, self.controllers)
|
||||||
|
|
||||||
def register_controllers(self, controller):
|
def register_controllers(self, controller):
|
||||||
"""
|
"""
|
||||||
Register each presentation controller (Impress, PPT etc) and store for later use
|
Register each presentation controller (Impress, PPT etc) and store for later use.
|
||||||
"""
|
"""
|
||||||
self.controllers[controller.name] = controller
|
self.controllers[controller.name] = controller
|
||||||
|
|
||||||
def check_pre_conditions(self):
|
def check_pre_conditions(self):
|
||||||
"""
|
"""
|
||||||
Check to see if we have any presentation software available
|
Check to see if we have any presentation software available. If not do not install the plugin.
|
||||||
If Not do not install the plugin.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'check_pre_conditions')
|
log.debug(u'check_pre_conditions')
|
||||||
controller_dir = os.path.join(
|
controller_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), u'presentations', u'lib')
|
||||||
AppLocation.get_directory(AppLocation.PluginsDir),
|
|
||||||
u'presentations', u'lib')
|
|
||||||
for filename in os.listdir(controller_dir):
|
for filename in os.listdir(controller_dir):
|
||||||
if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':
|
if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':
|
||||||
path = os.path.join(controller_dir, filename)
|
path = os.path.join(controller_dir, filename)
|
||||||
@ -146,7 +142,7 @@ class PresentationPlugin(Plugin):
|
|||||||
|
|
||||||
def about(self):
|
def about(self):
|
||||||
"""
|
"""
|
||||||
Return information about this plugin
|
Return information about this plugin.
|
||||||
"""
|
"""
|
||||||
about_text = translate('PresentationPlugin', '<strong>Presentation '
|
about_text = translate('PresentationPlugin', '<strong>Presentation '
|
||||||
'Plugin</strong><br />The presentation plugin provides the '
|
'Plugin</strong><br />The presentation plugin provides the '
|
||||||
@ -157,7 +153,7 @@ class PresentationPlugin(Plugin):
|
|||||||
|
|
||||||
def set_plugin_text_strings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin.
|
||||||
"""
|
"""
|
||||||
## Name PluginList ##
|
## Name PluginList ##
|
||||||
self.text_strings[StringContent.Name] = {
|
self.text_strings[StringContent.Name] = {
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`songusage` module contains the Song Usage plugin. The Song Usage
|
The :mod:`songusage` module contains the Song Usage plugin. The Song Usage plugin provides auditing capabilities for
|
||||||
plugin provides auditing capabilities for reporting the songs you are using to
|
reporting the songs you are using to copyright license organisations.
|
||||||
copyright license organisations.
|
|
||||||
"""
|
"""
|
||||||
|
@ -55,7 +55,8 @@ class Ui_SongUsageDeleteDialog(object):
|
|||||||
self.retranslateUi(song_usage_delete_dialog)
|
self.retranslateUi(song_usage_delete_dialog)
|
||||||
|
|
||||||
def retranslateUi(self, song_usage_delete_dialog):
|
def retranslateUi(self, song_usage_delete_dialog):
|
||||||
song_usage_delete_dialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Song Usage Data'))
|
song_usage_delete_dialog.setWindowTitle(
|
||||||
|
translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Song Usage Data'))
|
||||||
self.delete_label.setText(
|
self.delete_label.setText(
|
||||||
translate('SongUsagePlugin.SongUsageDeleteForm', 'Select the date up to which the song usage data '
|
translate('SongUsagePlugin.SongUsageDeleteForm', 'Select the date up to which the song usage data '
|
||||||
'should be deleted. All data recorded before this date will be permanently deleted.'))
|
'should be deleted. All data recorded before this date will be permanently deleted.'))
|
||||||
|
@ -81,7 +81,8 @@ class Ui_SongUsageDetailDialog(object):
|
|||||||
self.save_file_push_button.clicked.connect(song_usage_detail_dialog.define_output_location)
|
self.save_file_push_button.clicked.connect(song_usage_detail_dialog.define_output_location)
|
||||||
|
|
||||||
def retranslateUi(self, song_usage_detail_dialog):
|
def retranslateUi(self, song_usage_detail_dialog):
|
||||||
song_usage_detail_dialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Song Usage Extraction'))
|
song_usage_detail_dialog.setWindowTitle(
|
||||||
|
translate('SongUsagePlugin.SongUsageDetailForm', 'Song Usage Extraction'))
|
||||||
self.date_range_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Select Date Range'))
|
self.date_range_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Select Date Range'))
|
||||||
self.to_label.setText(translate('SongUsagePlugin.SongUsageDetailForm', 'to'))
|
self.to_label.setText(translate('SongUsagePlugin.SongUsageDetailForm', 'to'))
|
||||||
self.file_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Report Location'))
|
self.file_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Report Location'))
|
||||||
|
@ -36,12 +36,14 @@ from sqlalchemy.orm import mapper
|
|||||||
|
|
||||||
from openlp.core.lib.db import BaseModel, init_db
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
|
|
||||||
|
|
||||||
class SongUsageItem(BaseModel):
|
class SongUsageItem(BaseModel):
|
||||||
"""
|
"""
|
||||||
SongUsageItem model
|
SongUsageItem model
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def init_schema(url):
|
def init_schema(url):
|
||||||
"""
|
"""
|
||||||
Setup the songusage database connection and initialise the database schema
|
Setup the songusage database connection and initialise the database schema
|
||||||
|
@ -48,11 +48,11 @@ if QtCore.QDate().currentDate().month() < 9:
|
|||||||
|
|
||||||
|
|
||||||
__default_settings__ = {
|
__default_settings__ = {
|
||||||
u'songusage/db type': u'sqlite',
|
u'songusage/db type': u'sqlite',
|
||||||
u'songusage/active': False,
|
u'songusage/active': False,
|
||||||
u'songusage/to date': QtCore.QDate(YEAR, 8, 31),
|
u'songusage/to date': QtCore.QDate(YEAR, 8, 31),
|
||||||
u'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1),
|
u'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1),
|
||||||
u'songusage/last directory export': u''
|
u'songusage/last directory export': u''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,12 +76,10 @@ class SongUsagePlugin(Plugin):
|
|||||||
|
|
||||||
def add_tools_menu_item(self, tools_menu):
|
def add_tools_menu_item(self, tools_menu):
|
||||||
"""
|
"""
|
||||||
Give the SongUsage plugin the opportunity to add items to the
|
Give the SongUsage plugin the opportunity to add items to the **Tools** menu.
|
||||||
**Tools** menu.
|
|
||||||
|
|
||||||
``tools_menu``
|
``tools_menu``
|
||||||
The actual **Tools** menu item, so that your actions can
|
The actual **Tools** menu item, so that your actions can use it as their parent.
|
||||||
use it as their parent.
|
|
||||||
"""
|
"""
|
||||||
log.info(u'add tools menu')
|
log.info(u'add tools menu')
|
||||||
self.toolsMenu = tools_menu
|
self.toolsMenu = tools_menu
|
||||||
@ -218,8 +216,8 @@ class SongUsagePlugin(Plugin):
|
|||||||
self.song_usage_detail_form.exec_()
|
self.song_usage_detail_form.exec_()
|
||||||
|
|
||||||
def about(self):
|
def about(self):
|
||||||
about_text = translate('SongUsagePlugin', '<strong>SongUsage Plugin'
|
about_text = translate('SongUsagePlugin',
|
||||||
'</strong><br />This plugin tracks the usage of songs in services.')
|
'<strong>SongUsage Plugin</strong><br />This plugin tracks the usage of songs in services.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def set_plugin_text_strings(self):
|
def set_plugin_text_strings(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user