This commit is contained in:
Tim Bentley 2013-04-05 20:37:56 +01:00
commit e36706e3ec
11 changed files with 304 additions and 216 deletions

View File

@ -305,6 +305,7 @@ class Settings(QtCore.QSettings):
(u'bibles/bookname language', u'bibles/book name language', []), (u'bibles/bookname language', u'bibles/book name language', []),
(u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]), (u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]),
(u'songs/ccli number', u'general/ccli number', []), (u'songs/ccli number', u'general/ccli number', []),
(u'media/use phonon', u'', []),
# Changed during 2.1.x development. # Changed during 2.1.x development.
(u'advanced/stylesheet fix', u'', []), (u'advanced/stylesheet fix', u'', []),
(u'bibles/last directory 1', u'bibles/last directory import', []), (u'bibles/last directory 1', u'bibles/last directory import', []),

View File

@ -48,7 +48,7 @@ import sys
from inspect import getargspec from inspect import getargspec
__version__ = "N/A" __version__ = "N/A"
build_date = "Thu Mar 21 22:33:03 2013" build_date = "Mon Apr 1 23:47:38 2013"
if sys.version_info[0] > 2: if sys.version_info[0] > 2:
str = str str = str
@ -70,7 +70,7 @@ if sys.version_info[0] > 2:
if isinstance(b, bytes): if isinstance(b, bytes):
return b.decode(sys.getfilesystemencoding()) return b.decode(sys.getfilesystemencoding())
else: else:
return str(b) return b
else: else:
str = str str = str
unicode = unicode unicode = unicode
@ -278,6 +278,11 @@ def class_result(classname):
return classname(result) return classname(result)
return wrap_errcheck return wrap_errcheck
# Wrapper for the opaque struct libvlc_log_t
class Log(ctypes.Structure):
pass
Log_ptr = ctypes.POINTER(Log)
# FILE* ctypes wrapper, copied from # FILE* ctypes wrapper, copied from
# http://svn.python.org/projects/ctypes/trunk/ctypeslib/ctypeslib/contrib/pythonhdr.py # http://svn.python.org/projects/ctypes/trunk/ctypeslib/ctypeslib/contrib/pythonhdr.py
class FILE(ctypes.Structure): class FILE(ctypes.Structure):
@ -675,11 +680,14 @@ class Callback(ctypes.c_void_p):
pass pass
class LogCb(ctypes.c_void_p): class LogCb(ctypes.c_void_p):
"""Callback prototype for LibVLC log message handler. """Callback prototype for LibVLC log message handler.
\param data data pointer as given to L{libvlc_log_subscribe}() \param data data pointer as given to L{libvlc_log_set}()
\param level message level (@ref enum libvlc_log_level) \param level message level (@ref enum libvlc_log_level)
\param ctx message context (meta-informations about the message)
\param fmt printf() format string (as defined by ISO C11) \param fmt printf() format string (as defined by ISO C11)
\param args variable argument list for the format \param args variable argument list for the format
\note Log message handlers <b>must</b> be thread-safe. \note Log message handlers <b>must</b> be thread-safe.
\warning The message context pointer, the format string parameters and the
variable arguments are only valid until the callback returns.
""" """
pass pass
class VideoLockCb(ctypes.c_void_p): class VideoLockCb(ctypes.c_void_p):
@ -813,13 +821,16 @@ class CallbackDecorators(object):
Callback.__doc__ = '''Callback function notification Callback.__doc__ = '''Callback function notification
\param p_event the event triggering the callback \param p_event the event triggering the callback
''' '''
LogCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_void_p) LogCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, Log_ptr, ctypes.c_char_p, ctypes.c_void_p)
LogCb.__doc__ = '''Callback prototype for LibVLC log message handler. LogCb.__doc__ = '''Callback prototype for LibVLC log message handler.
\param data data pointer as given to L{libvlc_log_subscribe}() \param data data pointer as given to L{libvlc_log_set}()
\param level message level (@ref enum libvlc_log_level) \param level message level (@ref enum libvlc_log_level)
\param ctx message context (meta-informations about the message)
\param fmt printf() format string (as defined by ISO C11) \param fmt printf() format string (as defined by ISO C11)
\param args variable argument list for the format \param args variable argument list for the format
\note Log message handlers <b>must</b> be thread-safe. \note Log message handlers <b>must</b> be thread-safe.
\warning The message context pointer, the format string parameters and the
variable arguments are only valid until the callback returns.
''' '''
VideoLockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ListPOINTER(ctypes.c_void_p)) VideoLockCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ListPOINTER(ctypes.c_void_p))
VideoLockCb.__doc__ = '''Callback prototype to allocate and lock a picture buffer. VideoLockCb.__doc__ = '''Callback prototype to allocate and lock a picture buffer.
@ -1407,7 +1418,7 @@ class Instance(_Ctype):
@param name: interface name, or NULL for default. @param name: interface name, or NULL for default.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_add_intf(self, name) return libvlc_add_intf(self, str_to_bytes(name))
def set_user_agent(self, name, http): def set_user_agent(self, name, http):
'''Sets the application name. LibVLC passes this as the user agent string '''Sets the application name. LibVLC passes this as the user agent string
@ -1416,7 +1427,33 @@ class Instance(_Ctype):
@param http: HTTP User Agent, e.g. "FooBar/1.2.3 Python/2.6.0". @param http: HTTP User Agent, e.g. "FooBar/1.2.3 Python/2.6.0".
@version: LibVLC 1.1.1 or later. @version: LibVLC 1.1.1 or later.
''' '''
return libvlc_set_user_agent(self, name, http) return libvlc_set_user_agent(self, str_to_bytes(name), str_to_bytes(http))
def log_unset(self):
'''Unsets the logging callback for a LibVLC instance. This is rarely needed:
the callback is implicitly unset when the instance is destroyed.
This function will wait for any pending callbacks invocation to complete
(causing a deadlock if called from within the callback).
@version: LibVLC 2.1.0 or later.
'''
return libvlc_log_unset(self)
def log_set(self, data, p_instance):
'''Sets the logging callback for a LibVLC instance.
This function is thread-safe: it will wait for any pending callbacks
invocation to complete.
@param data: opaque data pointer for the callback function @note Some log messages (especially debug) are emitted by LibVLC while is being initialized. These messages cannot be captured with this interface. @warning A deadlock may occur if this function is called from the callback.
@param p_instance: libvlc instance.
@version: LibVLC 2.1.0 or later.
'''
return libvlc_log_set(self, data, p_instance)
def log_set_file(self, stream):
'''Sets up logging to a file.
@param stream: FILE pointer opened for writing (the FILE pointer must remain valid until L{log_unset}()).
@version: LibVLC 2.1.0 or later.
'''
return libvlc_log_set_file(self, stream)
def media_new_location(self, psz_mrl): def media_new_location(self, psz_mrl):
'''Create a media with a certain given media resource location, '''Create a media with a certain given media resource location,
@ -1429,7 +1466,7 @@ class Instance(_Ctype):
@param psz_mrl: the media location. @param psz_mrl: the media location.
@return: the newly created media or NULL on error. @return: the newly created media or NULL on error.
''' '''
return libvlc_media_new_location(self, psz_mrl) return libvlc_media_new_location(self, str_to_bytes(psz_mrl))
def media_new_path(self, path): def media_new_path(self, path):
'''Create a media for a certain file path. '''Create a media for a certain file path.
@ -1437,7 +1474,7 @@ class Instance(_Ctype):
@param path: local filesystem path. @param path: local filesystem path.
@return: the newly created media or NULL on error. @return: the newly created media or NULL on error.
''' '''
return libvlc_media_new_path(self, path) return libvlc_media_new_path(self, str_to_bytes(path))
def media_new_fd(self, fd): def media_new_fd(self, fd):
'''Create a media for an already open file descriptor. '''Create a media for an already open file descriptor.
@ -1465,14 +1502,14 @@ class Instance(_Ctype):
@param psz_name: the name of the node. @param psz_name: the name of the node.
@return: the new empty media or NULL on error. @return: the new empty media or NULL on error.
''' '''
return libvlc_media_new_as_node(self, psz_name) return libvlc_media_new_as_node(self, str_to_bytes(psz_name))
def media_discoverer_new_from_name(self, psz_name): def media_discoverer_new_from_name(self, psz_name):
'''Discover media service by name. '''Discover media service by name.
@param psz_name: service name. @param psz_name: service name.
@return: media discover object or NULL in case of error. @return: media discover object or NULL in case of error.
''' '''
return libvlc_media_discoverer_new_from_name(self, psz_name) return libvlc_media_discoverer_new_from_name(self, str_to_bytes(psz_name))
def media_library_new(self): def media_library_new(self):
'''Create an new Media Library object. '''Create an new Media Library object.
@ -1500,7 +1537,7 @@ class Instance(_Ctype):
@return: A NULL-terminated linked list of potential audio output devices. It must be freed it with L{audio_output_device_list_release}(). @return: A NULL-terminated linked list of potential audio output devices. It must be freed it with L{audio_output_device_list_release}().
@version: LibVLC 2.1.0 or later. @version: LibVLC 2.1.0 or later.
''' '''
return libvlc_audio_output_device_list_get(self, aout) return libvlc_audio_output_device_list_get(self, str_to_bytes(aout))
def vlm_release(self): def vlm_release(self):
'''Release the vlm instance related to the given L{Instance}. '''Release the vlm instance related to the given L{Instance}.
@ -1518,7 +1555,7 @@ class Instance(_Ctype):
@param b_loop: Should this broadcast be played in loop ? @param b_loop: Should this broadcast be played in loop ?
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_add_broadcast(self, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop) return libvlc_vlm_add_broadcast(self, str_to_bytes(psz_name), str_to_bytes(psz_input), str_to_bytes(psz_output), i_options, ppsz_options, b_enabled, b_loop)
def vlm_add_vod(self, psz_name, psz_input, i_options, ppsz_options, b_enabled, psz_mux): def vlm_add_vod(self, psz_name, psz_input, i_options, ppsz_options, b_enabled, psz_mux):
'''Add a vod, with one input. '''Add a vod, with one input.
@ -1530,14 +1567,14 @@ class Instance(_Ctype):
@param psz_mux: the muxer of the vod media. @param psz_mux: the muxer of the vod media.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_add_vod(self, psz_name, psz_input, i_options, ppsz_options, b_enabled, psz_mux) return libvlc_vlm_add_vod(self, str_to_bytes(psz_name), str_to_bytes(psz_input), i_options, ppsz_options, b_enabled, str_to_bytes(psz_mux))
def vlm_del_media(self, psz_name): def vlm_del_media(self, psz_name):
'''Delete a media (VOD or broadcast). '''Delete a media (VOD or broadcast).
@param psz_name: the media to delete. @param psz_name: the media to delete.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_del_media(self, psz_name) return libvlc_vlm_del_media(self, str_to_bytes(psz_name))
def vlm_set_enabled(self, psz_name, b_enabled): def vlm_set_enabled(self, psz_name, b_enabled):
'''Enable or disable a media (VOD or broadcast). '''Enable or disable a media (VOD or broadcast).
@ -1545,7 +1582,7 @@ class Instance(_Ctype):
@param b_enabled: the new status. @param b_enabled: the new status.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_set_enabled(self, psz_name, b_enabled) return libvlc_vlm_set_enabled(self, str_to_bytes(psz_name), b_enabled)
def vlm_set_output(self, psz_name, psz_output): def vlm_set_output(self, psz_name, psz_output):
'''Set the output for a media. '''Set the output for a media.
@ -1553,7 +1590,7 @@ class Instance(_Ctype):
@param psz_output: the output MRL (the parameter to the "sout" variable). @param psz_output: the output MRL (the parameter to the "sout" variable).
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_set_output(self, psz_name, psz_output) return libvlc_vlm_set_output(self, str_to_bytes(psz_name), str_to_bytes(psz_output))
def vlm_set_input(self, psz_name, psz_input): def vlm_set_input(self, psz_name, psz_input):
'''Set a media's input MRL. This will delete all existing inputs and '''Set a media's input MRL. This will delete all existing inputs and
@ -1562,7 +1599,7 @@ class Instance(_Ctype):
@param psz_input: the input MRL. @param psz_input: the input MRL.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_set_input(self, psz_name, psz_input) return libvlc_vlm_set_input(self, str_to_bytes(psz_name), str_to_bytes(psz_input))
def vlm_add_input(self, psz_name, psz_input): def vlm_add_input(self, psz_name, psz_input):
'''Add a media's input MRL. This will add the specified one. '''Add a media's input MRL. This will add the specified one.
@ -1570,7 +1607,7 @@ class Instance(_Ctype):
@param psz_input: the input MRL. @param psz_input: the input MRL.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_add_input(self, psz_name, psz_input) return libvlc_vlm_add_input(self, str_to_bytes(psz_name), str_to_bytes(psz_input))
def vlm_set_loop(self, psz_name, b_loop): def vlm_set_loop(self, psz_name, b_loop):
'''Set a media's loop status. '''Set a media's loop status.
@ -1578,7 +1615,7 @@ class Instance(_Ctype):
@param b_loop: the new status. @param b_loop: the new status.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_set_loop(self, psz_name, b_loop) return libvlc_vlm_set_loop(self, str_to_bytes(psz_name), b_loop)
def vlm_set_mux(self, psz_name, psz_mux): def vlm_set_mux(self, psz_name, psz_mux):
'''Set a media's vod muxer. '''Set a media's vod muxer.
@ -1586,7 +1623,7 @@ class Instance(_Ctype):
@param psz_mux: the new muxer. @param psz_mux: the new muxer.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_set_mux(self, psz_name, psz_mux) return libvlc_vlm_set_mux(self, str_to_bytes(psz_name), str_to_bytes(psz_mux))
def vlm_change_media(self, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop): def vlm_change_media(self, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop):
'''Edit the parameters of a media. This will delete all existing inputs and '''Edit the parameters of a media. This will delete all existing inputs and
@ -1600,28 +1637,28 @@ class Instance(_Ctype):
@param b_loop: Should this broadcast be played in loop ? @param b_loop: Should this broadcast be played in loop ?
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_change_media(self, psz_name, psz_input, psz_output, i_options, ppsz_options, b_enabled, b_loop) return libvlc_vlm_change_media(self, str_to_bytes(psz_name), str_to_bytes(psz_input), str_to_bytes(psz_output), i_options, ppsz_options, b_enabled, b_loop)
def vlm_play_media(self, psz_name): def vlm_play_media(self, psz_name):
'''Play the named broadcast. '''Play the named broadcast.
@param psz_name: the name of the broadcast. @param psz_name: the name of the broadcast.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_play_media(self, psz_name) return libvlc_vlm_play_media(self, str_to_bytes(psz_name))
def vlm_stop_media(self, psz_name): def vlm_stop_media(self, psz_name):
'''Stop the named broadcast. '''Stop the named broadcast.
@param psz_name: the name of the broadcast. @param psz_name: the name of the broadcast.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_stop_media(self, psz_name) return libvlc_vlm_stop_media(self, str_to_bytes(psz_name))
def vlm_pause_media(self, psz_name): def vlm_pause_media(self, psz_name):
'''Pause the named broadcast. '''Pause the named broadcast.
@param psz_name: the name of the broadcast. @param psz_name: the name of the broadcast.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_pause_media(self, psz_name) return libvlc_vlm_pause_media(self, str_to_bytes(psz_name))
def vlm_seek_media(self, psz_name, f_percentage): def vlm_seek_media(self, psz_name, f_percentage):
'''Seek in the named broadcast. '''Seek in the named broadcast.
@ -1629,7 +1666,7 @@ class Instance(_Ctype):
@param f_percentage: the percentage to seek to. @param f_percentage: the percentage to seek to.
@return: 0 on success, -1 on error. @return: 0 on success, -1 on error.
''' '''
return libvlc_vlm_seek_media(self, psz_name, f_percentage) return libvlc_vlm_seek_media(self, str_to_bytes(psz_name), f_percentage)
def vlm_show_media(self, psz_name): def vlm_show_media(self, psz_name):
'''Return information about the named media as a JSON '''Return information about the named media as a JSON
@ -1643,7 +1680,7 @@ class Instance(_Ctype):
@param psz_name: the name of the media, if the name is an empty string, all media is described. @param psz_name: the name of the media, if the name is an empty string, all media is described.
@return: string with information about named media, or NULL on error. @return: string with information about named media, or NULL on error.
''' '''
return libvlc_vlm_show_media(self, psz_name) return libvlc_vlm_show_media(self, str_to_bytes(psz_name))
def vlm_get_media_instance_position(self, psz_name, i_instance): def vlm_get_media_instance_position(self, psz_name, i_instance):
'''Get vlm_media instance position by name or instance id. '''Get vlm_media instance position by name or instance id.
@ -1651,7 +1688,7 @@ class Instance(_Ctype):
@param i_instance: instance id. @param i_instance: instance id.
@return: position as float or -1. on error. @return: position as float or -1. on error.
''' '''
return libvlc_vlm_get_media_instance_position(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_position(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_time(self, psz_name, i_instance): def vlm_get_media_instance_time(self, psz_name, i_instance):
'''Get vlm_media instance time by name or instance id. '''Get vlm_media instance time by name or instance id.
@ -1659,7 +1696,7 @@ class Instance(_Ctype):
@param i_instance: instance id. @param i_instance: instance id.
@return: time as integer or -1 on error. @return: time as integer or -1 on error.
''' '''
return libvlc_vlm_get_media_instance_time(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_time(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_length(self, psz_name, i_instance): def vlm_get_media_instance_length(self, psz_name, i_instance):
'''Get vlm_media instance length by name or instance id. '''Get vlm_media instance length by name or instance id.
@ -1667,7 +1704,7 @@ class Instance(_Ctype):
@param i_instance: instance id. @param i_instance: instance id.
@return: length of media item or -1 on error. @return: length of media item or -1 on error.
''' '''
return libvlc_vlm_get_media_instance_length(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_length(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_rate(self, psz_name, i_instance): def vlm_get_media_instance_rate(self, psz_name, i_instance):
'''Get vlm_media instance playback rate by name or instance id. '''Get vlm_media instance playback rate by name or instance id.
@ -1675,7 +1712,7 @@ class Instance(_Ctype):
@param i_instance: instance id. @param i_instance: instance id.
@return: playback rate or -1 on error. @return: playback rate or -1 on error.
''' '''
return libvlc_vlm_get_media_instance_rate(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_rate(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_title(self, psz_name, i_instance): def vlm_get_media_instance_title(self, psz_name, i_instance):
'''Get vlm_media instance title number by name or instance id. '''Get vlm_media instance title number by name or instance id.
@ -1684,7 +1721,7 @@ class Instance(_Ctype):
@return: title as number or -1 on error. @return: title as number or -1 on error.
@bug: will always return 0. @bug: will always return 0.
''' '''
return libvlc_vlm_get_media_instance_title(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_title(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_chapter(self, psz_name, i_instance): def vlm_get_media_instance_chapter(self, psz_name, i_instance):
'''Get vlm_media instance chapter number by name or instance id. '''Get vlm_media instance chapter number by name or instance id.
@ -1693,7 +1730,7 @@ class Instance(_Ctype):
@return: chapter as number or -1 on error. @return: chapter as number or -1 on error.
@bug: will always return 0. @bug: will always return 0.
''' '''
return libvlc_vlm_get_media_instance_chapter(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_chapter(self, str_to_bytes(psz_name), i_instance)
def vlm_get_media_instance_seekable(self, psz_name, i_instance): def vlm_get_media_instance_seekable(self, psz_name, i_instance):
'''Is libvlc instance seekable ? '''Is libvlc instance seekable ?
@ -1702,7 +1739,7 @@ class Instance(_Ctype):
@return: 1 if seekable, 0 if not, -1 if media does not exist. @return: 1 if seekable, 0 if not, -1 if media does not exist.
@bug: will always return 0. @bug: will always return 0.
''' '''
return libvlc_vlm_get_media_instance_seekable(self, psz_name, i_instance) return libvlc_vlm_get_media_instance_seekable(self, str_to_bytes(psz_name), i_instance)
def vlm_get_event_manager(self): def vlm_get_event_manager(self):
'''Get libvlc_event_manager from a vlm media. '''Get libvlc_event_manager from a vlm media.
@ -1751,7 +1788,7 @@ class Media(_Ctype):
self.add_option(o) self.add_option(o)
def add_option(self, ppsz_options): def add_option(self, psz_options):
'''Add an option to the media. '''Add an option to the media.
This option will be used to determine how the media_player will This option will be used to determine how the media_player will
read the media. This allows to use VLC's advanced read the media. This allows to use VLC's advanced
@ -1763,11 +1800,11 @@ class Media(_Ctype):
Specifically, due to architectural issues most audio and video options, Specifically, due to architectural issues most audio and video options,
such as text renderer options, have no effects on an individual media. such as text renderer options, have no effects on an individual media.
These options must be set through L{new}() instead. These options must be set through L{new}() instead.
@param ppsz_options: the options (as a string). @param psz_options: the options (as a string).
''' '''
return libvlc_media_add_option(self, ppsz_options) return libvlc_media_add_option(self, str_to_bytes(psz_options))
def add_option_flag(self, ppsz_options, i_flags): def add_option_flag(self, psz_options, i_flags):
'''Add an option to the media with configurable flags. '''Add an option to the media with configurable flags.
This option will be used to determine how the media_player will This option will be used to determine how the media_player will
read the media. This allows to use VLC's advanced read the media. This allows to use VLC's advanced
@ -1777,10 +1814,10 @@ class Media(_Ctype):
specifically, due to architectural issues, video-related options specifically, due to architectural issues, video-related options
such as text renderer options cannot be set on a single media. They such as text renderer options cannot be set on a single media. They
must be set on the whole libvlc instance instead. must be set on the whole libvlc instance instead.
@param ppsz_options: the options (as a string). @param psz_options: the options (as a string).
@param i_flags: the flags for this option. @param i_flags: the flags for this option.
''' '''
return libvlc_media_add_option_flag(self, ppsz_options, i_flags) return libvlc_media_add_option_flag(self, str_to_bytes(psz_options), i_flags)
def retain(self): def retain(self):
'''Retain a reference to a media descriptor object (libvlc_media_t). Use '''Retain a reference to a media descriptor object (libvlc_media_t). Use
@ -1829,7 +1866,7 @@ class Media(_Ctype):
@param e_meta: the meta to write. @param e_meta: the meta to write.
@param psz_value: the media's meta. @param psz_value: the media's meta.
''' '''
return libvlc_media_set_meta(self, e_meta, psz_value) return libvlc_media_set_meta(self, e_meta, str_to_bytes(psz_value))
def save_meta(self): def save_meta(self):
'''Save the meta previously set. '''Save the meta previously set.
@ -2490,7 +2527,7 @@ class MediaPlayer(_Ctype):
@version: LibVLC 1.1.1 or later. @version: LibVLC 1.1.1 or later.
@bug: All pixel planes are expected to have the same pitch. To use the YCbCr color space with chrominance subsampling, consider using L{video_set_format_callbacks}() instead. @bug: All pixel planes are expected to have the same pitch. To use the YCbCr color space with chrominance subsampling, consider using L{video_set_format_callbacks}() instead.
''' '''
return libvlc_video_set_format(self, chroma, width, height, pitch) return libvlc_video_set_format(self, str_to_bytes(chroma), width, height, pitch)
def video_set_format_callbacks(self, setup, cleanup): def video_set_format_callbacks(self, setup, cleanup):
'''Set decoded video chroma and dimensions. This only works in combination with '''Set decoded video chroma and dimensions. This only works in combination with
@ -2617,7 +2654,7 @@ class MediaPlayer(_Ctype):
@param channels: channels count. @param channels: channels count.
@version: LibVLC 2.0.0 or later. @version: LibVLC 2.0.0 or later.
''' '''
return libvlc_audio_set_format(self, format, rate, channels) return libvlc_audio_set_format(self, str_to_bytes(format), rate, channels)
def get_length(self): def get_length(self):
'''Get the current movie length (in ms). '''Get the current movie length (in ms).
@ -2843,7 +2880,7 @@ class MediaPlayer(_Ctype):
'''Set new video aspect ratio. '''Set new video aspect ratio.
@param psz_aspect: new video aspect-ratio or NULL to reset to default @note Invalid aspect ratios are ignored. @param psz_aspect: new video aspect-ratio or NULL to reset to default @note Invalid aspect ratios are ignored.
''' '''
return libvlc_video_set_aspect_ratio(self, psz_aspect) return libvlc_video_set_aspect_ratio(self, str_to_bytes(psz_aspect))
def video_get_spu(self): def video_get_spu(self):
'''Get current video subtitle. '''Get current video subtitle.
@ -2859,7 +2896,7 @@ class MediaPlayer(_Ctype):
def video_set_spu(self, i_spu): def video_set_spu(self, i_spu):
'''Set new video subtitle. '''Set new video subtitle.
@param i_spu: new video subtitle to select. @param i_spu: video subtitle track to select (i_id from track description).
@return: 0 on success, -1 if out of range. @return: 0 on success, -1 if out of range.
''' '''
return libvlc_video_set_spu(self, i_spu) return libvlc_video_set_spu(self, i_spu)
@ -2869,7 +2906,7 @@ class MediaPlayer(_Ctype):
@param psz_subtitle: new video subtitle file. @param psz_subtitle: new video subtitle file.
@return: the success status (boolean). @return: the success status (boolean).
''' '''
return libvlc_video_set_subtitle_file(self, psz_subtitle) return libvlc_video_set_subtitle_file(self, str_to_bytes(psz_subtitle))
def video_get_spu_delay(self): def video_get_spu_delay(self):
'''Get the current subtitle delay. Positive values means subtitles are being '''Get the current subtitle delay. Positive values means subtitles are being
@ -2900,7 +2937,7 @@ class MediaPlayer(_Ctype):
'''Set new crop filter geometry. '''Set new crop filter geometry.
@param psz_geometry: new crop filter geometry (NULL to unset). @param psz_geometry: new crop filter geometry (NULL to unset).
''' '''
return libvlc_video_set_crop_geometry(self, psz_geometry) return libvlc_video_set_crop_geometry(self, str_to_bytes(psz_geometry))
def video_get_teletext(self): def video_get_teletext(self):
'''Get current teletext page requested. '''Get current teletext page requested.
@ -2948,13 +2985,13 @@ class MediaPlayer(_Ctype):
@param i_height: the snapshot's height. @param i_height: the snapshot's height.
@return: 0 on success, -1 if the video was not found. @return: 0 on success, -1 if the video was not found.
''' '''
return libvlc_video_take_snapshot(self, num, psz_filepath, i_width, i_height) return libvlc_video_take_snapshot(self, num, str_to_bytes(psz_filepath), i_width, i_height)
def video_set_deinterlace(self, psz_mode): def video_set_deinterlace(self, psz_mode):
'''Enable or disable deinterlace filter. '''Enable or disable deinterlace filter.
@param psz_mode: type of deinterlace filter, NULL to disable. @param psz_mode: type of deinterlace filter, NULL to disable.
''' '''
return libvlc_video_set_deinterlace(self, psz_mode) return libvlc_video_set_deinterlace(self, str_to_bytes(psz_mode))
def video_get_marquee_int(self, option): def video_get_marquee_int(self, option):
'''Get an integer marquee option value. '''Get an integer marquee option value.
@ -2982,7 +3019,7 @@ class MediaPlayer(_Ctype):
@param option: marq option to set See libvlc_video_marquee_string_option_t. @param option: marq option to set See libvlc_video_marquee_string_option_t.
@param psz_text: marq option value. @param psz_text: marq option value.
''' '''
return libvlc_video_set_marquee_string(self, option, psz_text) return libvlc_video_set_marquee_string(self, option, str_to_bytes(psz_text))
def video_get_logo_int(self, option): def video_get_logo_int(self, option):
'''Get integer logo option. '''Get integer logo option.
@ -3006,7 +3043,7 @@ class MediaPlayer(_Ctype):
@param option: logo option to set, values of libvlc_video_logo_option_t. @param option: logo option to set, values of libvlc_video_logo_option_t.
@param psz_value: logo option value. @param psz_value: logo option value.
''' '''
return libvlc_video_set_logo_string(self, option, psz_value) return libvlc_video_set_logo_string(self, option, str_to_bytes(psz_value))
def video_get_adjust_int(self, option): def video_get_adjust_int(self, option):
'''Get integer adjust option. '''Get integer adjust option.
@ -3049,7 +3086,7 @@ class MediaPlayer(_Ctype):
@param psz_name: name of audio output, use psz_name of See L{AudioOutput}. @param psz_name: name of audio output, use psz_name of See L{AudioOutput}.
@return: 0 if function succeded, -1 on error. @return: 0 if function succeded, -1 on error.
''' '''
return libvlc_audio_output_set(self, psz_name) return libvlc_audio_output_set(self, str_to_bytes(psz_name))
def audio_output_device_set(self, psz_audio_output, psz_device_id): def audio_output_device_set(self, psz_audio_output, psz_device_id):
'''Configures an explicit audio output device for a given audio output plugin. '''Configures an explicit audio output device for a given audio output plugin.
@ -3065,7 +3102,7 @@ class MediaPlayer(_Ctype):
@param psz_device_id: device. @param psz_device_id: device.
@return: Nothing. Errors are ignored. @return: Nothing. Errors are ignored.
''' '''
return libvlc_audio_output_device_set(self, psz_audio_output, psz_device_id) return libvlc_audio_output_device_set(self, str_to_bytes(psz_audio_output), str_to_bytes(psz_device_id))
def audio_toggle_mute(self): def audio_toggle_mute(self):
'''Toggle mute status. '''Toggle mute status.
@ -3314,44 +3351,43 @@ def libvlc_event_type_name(event_type):
ctypes.c_char_p, ctypes.c_uint) ctypes.c_char_p, ctypes.c_uint)
return f(event_type) return f(event_type)
def libvlc_log_subscribe(sub, cb, data): def libvlc_log_unset(p_instance):
'''Registers a logging callback to LibVLC. '''Unsets the logging callback for a LibVLC instance. This is rarely needed:
This function is thread-safe. the callback is implicitly unset when the instance is destroyed.
@param sub: uninitialized subscriber structure. This function will wait for any pending callbacks invocation to complete
(causing a deadlock if called from within the callback).
@param p_instance: libvlc instance.
@version: LibVLC 2.1.0 or later.
'''
f = _Cfunctions.get('libvlc_log_unset', None) or \
_Cfunction('libvlc_log_unset', ((1,),), None,
None, Instance)
return f(p_instance)
def libvlc_log_set(cb, data, p_instance):
'''Sets the logging callback for a LibVLC instance.
This function is thread-safe: it will wait for any pending callbacks
invocation to complete.
@param cb: callback function pointer. @param cb: callback function pointer.
@param data: opaque data pointer for the callback function @note Some log messages (especially debug) are emitted by LibVLC while initializing, before any LibVLC instance even exists. Thus this function does not require a LibVLC instance parameter. @warning As a consequence of not depending on a LibVLC instance, all logging callbacks are shared by all LibVLC instances within the process / address space. This also enables log messages to be emitted by LibVLC components that are not specific to any given LibVLC instance. @warning Do not call this function from within a logging callback. It would trigger a dead lock. @param data: opaque data pointer for the callback function @note Some log messages (especially debug) are emitted by LibVLC while is being initialized. These messages cannot be captured with this interface. @warning A deadlock may occur if this function is called from the callback.
@param p_instance: libvlc instance.
@version: LibVLC 2.1.0 or later. @version: LibVLC 2.1.0 or later.
''' '''
f = _Cfunctions.get('libvlc_log_subscribe', None) or \ f = _Cfunctions.get('libvlc_log_set', None) or \
_Cfunction('libvlc_log_subscribe', ((1,), (1,), (1,),), None, _Cfunction('libvlc_log_set', ((1,), (1,), (1,),), None,
None, ctypes.c_void_p, LogCb, ctypes.c_void_p) None, Instance, LogCb, ctypes.c_void_p)
return f(sub, cb, data) return f(cb, data, p_instance)
def libvlc_log_subscribe_file(sub, stream): def libvlc_log_set_file(p_instance, stream):
'''Registers a logging callback to a file. '''Sets up logging to a file.
@param stream: FILE pointer opened for writing (the FILE pointer must remain valid until L{libvlc_log_unsubscribe}()). @param p_instance: libvlc instance.
@param stream: FILE pointer opened for writing (the FILE pointer must remain valid until L{libvlc_log_unset}()).
@version: LibVLC 2.1.0 or later. @version: LibVLC 2.1.0 or later.
''' '''
f = _Cfunctions.get('libvlc_log_subscribe_file', None) or \ f = _Cfunctions.get('libvlc_log_set_file', None) or \
_Cfunction('libvlc_log_subscribe_file', ((1,), (1,),), None, _Cfunction('libvlc_log_set_file', ((1,), (1,),), None,
None, ctypes.c_void_p, FILE_ptr) None, Instance, FILE_ptr)
return f(sub, stream) return f(p_instance, stream)
def libvlc_log_unsubscribe(sub):
'''Deregisters a logging callback from LibVLC.
This function is thread-safe.
@note: After (and only after) L{libvlc_log_unsubscribe}() has returned,
LibVLC warrants that there are no more pending calls of the subscription
callback function.
@warning: Do not call this function from within a logging callback.
It would trigger a dead lock.
@param sub: initialized subscriber structure.
@version: LibVLC 2.1.0 or later.
'''
f = _Cfunctions.get('libvlc_log_unsubscribe', None) or \
_Cfunction('libvlc_log_unsubscribe', ((1,),), None,
None, ctypes.c_void_p)
return f(sub)
def libvlc_module_description_list_release(p_list): def libvlc_module_description_list_release(p_list):
'''Release a list of module descriptions. '''Release a list of module descriptions.
@ -3460,7 +3496,7 @@ def libvlc_media_new_as_node(p_instance, psz_name):
ctypes.c_void_p, Instance, ctypes.c_char_p) ctypes.c_void_p, Instance, ctypes.c_char_p)
return f(p_instance, psz_name) return f(p_instance, psz_name)
def libvlc_media_add_option(p_md, ppsz_options): def libvlc_media_add_option(p_md, psz_options):
'''Add an option to the media. '''Add an option to the media.
This option will be used to determine how the media_player will This option will be used to determine how the media_player will
read the media. This allows to use VLC's advanced read the media. This allows to use VLC's advanced
@ -3473,14 +3509,14 @@ def libvlc_media_add_option(p_md, ppsz_options):
such as text renderer options, have no effects on an individual media. such as text renderer options, have no effects on an individual media.
These options must be set through L{libvlc_new}() instead. These options must be set through L{libvlc_new}() instead.
@param p_md: the media descriptor. @param p_md: the media descriptor.
@param ppsz_options: the options (as a string). @param psz_options: the options (as a string).
''' '''
f = _Cfunctions.get('libvlc_media_add_option', None) or \ f = _Cfunctions.get('libvlc_media_add_option', None) or \
_Cfunction('libvlc_media_add_option', ((1,), (1,),), None, _Cfunction('libvlc_media_add_option', ((1,), (1,),), None,
None, Media, ctypes.c_char_p) None, Media, ctypes.c_char_p)
return f(p_md, ppsz_options) return f(p_md, psz_options)
def libvlc_media_add_option_flag(p_md, ppsz_options, i_flags): def libvlc_media_add_option_flag(p_md, psz_options, i_flags):
'''Add an option to the media with configurable flags. '''Add an option to the media with configurable flags.
This option will be used to determine how the media_player will This option will be used to determine how the media_player will
read the media. This allows to use VLC's advanced read the media. This allows to use VLC's advanced
@ -3491,13 +3527,13 @@ def libvlc_media_add_option_flag(p_md, ppsz_options, i_flags):
such as text renderer options cannot be set on a single media. They such as text renderer options cannot be set on a single media. They
must be set on the whole libvlc instance instead. must be set on the whole libvlc instance instead.
@param p_md: the media descriptor. @param p_md: the media descriptor.
@param ppsz_options: the options (as a string). @param psz_options: the options (as a string).
@param i_flags: the flags for this option. @param i_flags: the flags for this option.
''' '''
f = _Cfunctions.get('libvlc_media_add_option_flag', None) or \ f = _Cfunctions.get('libvlc_media_add_option_flag', None) or \
_Cfunction('libvlc_media_add_option_flag', ((1,), (1,), (1,),), None, _Cfunction('libvlc_media_add_option_flag', ((1,), (1,), (1,),), None,
None, Media, ctypes.c_char_p, ctypes.c_uint) None, Media, ctypes.c_char_p, ctypes.c_uint)
return f(p_md, ppsz_options, i_flags) return f(p_md, psz_options, i_flags)
def libvlc_media_retain(p_md): def libvlc_media_retain(p_md):
'''Retain a reference to a media descriptor object (libvlc_media_t). Use '''Retain a reference to a media descriptor object (libvlc_media_t). Use
@ -4949,12 +4985,12 @@ def libvlc_video_get_spu_description(p_mi):
def libvlc_video_set_spu(p_mi, i_spu): def libvlc_video_set_spu(p_mi, i_spu):
'''Set new video subtitle. '''Set new video subtitle.
@param p_mi: the media player. @param p_mi: the media player.
@param i_spu: new video subtitle to select. @param i_spu: video subtitle track to select (i_id from track description).
@return: 0 on success, -1 if out of range. @return: 0 on success, -1 if out of range.
''' '''
f = _Cfunctions.get('libvlc_video_set_spu', None) or \ f = _Cfunctions.get('libvlc_video_set_spu', None) or \
_Cfunction('libvlc_video_set_spu', ((1,), (1,),), None, _Cfunction('libvlc_video_set_spu', ((1,), (1,),), None,
ctypes.c_int, MediaPlayer, ctypes.c_uint) ctypes.c_int, MediaPlayer, ctypes.c_int)
return f(p_mi, i_spu) return f(p_mi, i_spu)
def libvlc_video_set_subtitle_file(p_mi, psz_subtitle): def libvlc_video_set_subtitle_file(p_mi, psz_subtitle):
@ -5791,7 +5827,7 @@ def libvlc_vlm_get_event_manager(p_instance):
# libvlc_printerr # libvlc_printerr
# libvlc_set_exit_handler # libvlc_set_exit_handler
# 18 function(s) not wrapped as methods: # 15 function(s) not wrapped as methods:
# libvlc_audio_output_device_list_release # libvlc_audio_output_device_list_release
# libvlc_audio_output_list_release # libvlc_audio_output_list_release
# libvlc_clearerr # libvlc_clearerr
@ -5802,9 +5838,6 @@ def libvlc_vlm_get_event_manager(p_instance):
# libvlc_get_changeset # libvlc_get_changeset
# libvlc_get_compiler # libvlc_get_compiler
# libvlc_get_version # libvlc_get_version
# libvlc_log_subscribe
# libvlc_log_subscribe_file
# libvlc_log_unsubscribe
# libvlc_media_tracks_release # libvlc_media_tracks_release
# libvlc_module_description_list_release # libvlc_module_description_list_release
# libvlc_new # libvlc_new

View File

@ -84,9 +84,8 @@ class ServiceManagerList(QtGui.QTreeWidget):
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
""" """
Drag and drop event does not care what data is selected Drag and drop event does not care what data is selected as the recipient will use events to request the data
as the recipient will use events to request the data move move just tell it what plugin to call
just tell it what plugin to call
""" """
if event.buttons() != QtCore.Qt.LeftButton: if event.buttons() != QtCore.Qt.LeftButton:
event.ignore() event.ignore()
@ -235,18 +234,22 @@ class ServiceManagerDialog(object):
icon=u':/general/general_edit.png', triggers=self.create_custom) icon=u':/general/general_edit.png', triggers=self.create_custom)
self.menu.addSeparator() self.menu.addSeparator()
# Add AutoPlay menu actions # Add AutoPlay menu actions
self.auto_play_slides_group = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Auto play slides')) self.auto_play_slides_menu = QtGui.QMenu(translate('OpenLP.ServiceManager', '&Auto play slides'))
self.menu.addMenu(self.auto_play_slides_group) self.menu.addMenu(self.auto_play_slides_menu)
self.auto_play_slides_loop = create_widget_action(self.auto_play_slides_group, auto_play_slides_group = QtGui.QActionGroup(self.auto_play_slides_menu)
auto_play_slides_group.setExclusive(True)
self.auto_play_slides_loop = create_widget_action(self.auto_play_slides_menu,
text=translate('OpenLP.ServiceManager', 'Auto play slides &Loop'), text=translate('OpenLP.ServiceManager', 'Auto play slides &Loop'),
checked=False, triggers=self.toggle_auto_play_slides_loop) checked=False, triggers=self.toggle_auto_play_slides_loop)
self.auto_play_slides_once = create_widget_action(self.auto_play_slides_group, auto_play_slides_group.addAction(self.auto_play_slides_loop)
self.auto_play_slides_once = create_widget_action(self.auto_play_slides_menu,
text=translate('OpenLP.ServiceManager', 'Auto play slides &Once'), text=translate('OpenLP.ServiceManager', 'Auto play slides &Once'),
checked=False, triggers=self.toggle_auto_play_slides_once) checked=False, triggers=self.toggle_auto_play_slides_once)
self.auto_play_slides_group.addSeparator() auto_play_slides_group.addAction(self.auto_play_slides_once)
self.timed_slide_interval = create_widget_action(self.auto_play_slides_group, self.auto_play_slides_menu.addSeparator()
self.timed_slide_interval = create_widget_action(self.auto_play_slides_menu,
text=translate('OpenLP.ServiceManager', '&Delay between slides'), text=translate('OpenLP.ServiceManager', '&Delay between slides'),
checked=False, triggers=self.on_timed_slide_interval) triggers=self.on_timed_slide_interval)
self.menu.addSeparator() self.menu.addSeparator()
self.preview_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'), self.preview_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'),
icon=u':/general/general_preview.png', triggers=self.make_preview) icon=u':/general/general_preview.png', triggers=self.make_preview)
@ -283,10 +286,9 @@ class ServiceManagerDialog(object):
class ServiceManager(QtGui.QWidget, ServiceManagerDialog): class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
""" """
Manages the services. This involves taking text strings from plugins and Manages the services. This involves taking text strings from plugins and adding them to the service. This service
adding them to the service. This service can then be zipped up with all can then be zipped up with all the resources used into one OSZ or oszl file for use on any OpenLP v2 installation.
the resources used into one OSZ or oszl file for use on any OpenLP v2 Also handles the UI tasks of moving things up and down etc.
installation. Also handles the UI tasks of moving things up and down etc.
""" """
def __init__(self, parent=None): def __init__(self, parent=None):
""" """
@ -317,8 +319,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def set_modified(self, modified=True): def set_modified(self, modified=True):
""" """
Setter for property "modified". Sets whether or not the current service Setter for property "modified". Sets whether or not the current service has been modified.
has been modified.
""" """
if modified: if modified:
self.service_id += 1 self.service_id += 1
@ -362,7 +363,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def supported_suffixes(self, suffix): def supported_suffixes(self, suffix):
""" """
Adds Suffixes supported to the master list. Called from Plugins. Adds Suffixes supported to the master list. Called from Plugins.
``suffix`` ``suffix``
New Suffix to be supported New Suffix to be supported
@ -385,12 +386,10 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def on_load_service_clicked(self, load_file=None): def on_load_service_clicked(self, load_file=None):
""" """
Loads the service file and saves the existing one it there is one Loads the service file and saves the existing one it there is one unchanged.
unchanged
``load_file`` ``load_file``
The service file to the loaded. Will be None is from menu so The service file to the loaded. Will be None is from menu so selection will be required.
selection will be required.
""" """
if self.is_modified(): if self.is_modified():
result = self.save_modified_service() result = self.save_modified_service()
@ -446,10 +445,9 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
""" """
Save the current service file. Save the current service file.
A temporary file is created so that we don't overwrite the existing one A temporary file is created so that we don't overwrite the existing one and leave a mangled service file should
and leave a mangled service file should there be an error when saving. there be an error when saving. Audio files are also copied into the service manager directory, and then packaged
Audio files are also copied into the service manager directory, and into the zip file.
then packaged into the zip file.
""" """
if not self.file_name(): if not self.file_name():
return self.save_file_as() return self.save_file_as()
@ -515,8 +513,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
total_size += file_size total_size += file_size
log.debug(u'ServiceManager.save_file - ZIP contents size is %i bytes' % total_size) log.debug(u'ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
service_content = cPickle.dumps(service) service_content = cPickle.dumps(service)
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX.
# extracted using unzip in UNIX.
allow_zip_64 = (total_size > 2147483648 + len(service_content)) allow_zip_64 = (total_size > 2147483648 + len(service_content))
log.debug(u'ServiceManager.save_file - allowZip64 is %s' % allow_zip_64) log.debug(u'ServiceManager.save_file - allowZip64 is %s' % allow_zip_64)
zip_file = None zip_file = None
@ -524,18 +521,15 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
try: try:
zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64)
# First we add service contents. # First we add service contents. We save ALL file_names into ZIP using UTF-8.
# We save ALL file_names into ZIP using UTF-8.
zip_file.writestr(service_file_name.encode(u'utf-8'), service_content) zip_file.writestr(service_file_name.encode(u'utf-8'), service_content)
# Finally add all the listed media files. # Finally add all the listed media files.
for write_from in write_list: for write_from in write_list:
zip_file.write(write_from, write_from.encode(u'utf-8')) zip_file.write(write_from, write_from.encode(u'utf-8'))
for audio_from, audio_to in audio_files: for audio_from, audio_to in audio_files:
if audio_from.startswith(u'audio'): if audio_from.startswith(u'audio'):
# When items are saved, they get new unique_identifier. Let's copy the # When items are saved, they get new unique_identifier. Let's copy the file to the new location.
# file to the new location. Unused files can be ignored, # Unused files can be ignored, OpenLP automatically cleans up the service manager dir on exit.
# OpenLP automatically cleans up the service manager dir on
# exit.
audio_from = os.path.join(self.servicePath, audio_from) audio_from = os.path.join(self.servicePath, audio_from)
save_file = os.path.join(self.servicePath, audio_to) save_file = os.path.join(self.servicePath, audio_to)
save_path = os.path.split(save_file)[0] save_path = os.path.split(save_file)[0]
@ -588,7 +582,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
for item in self.service_items: for item in self.service_items:
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
service_item = item[u'service_item'].get_service_repr(self._save_lite) service_item = item[u'service_item'].get_service_repr(self._save_lite)
#@todo check for file item on save. #TODO: check for file item on save.
service.append({u'serviceitem': service_item}) service.append({u'serviceitem': service_item})
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
service_content = cPickle.dumps(service) service_content = cPickle.dumps(service)
@ -623,8 +617,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def save_file_as(self): def save_file_as(self):
""" """
Get a file name and then call :func:`ServiceManager.save_file` to Get a file name and then call :func:`ServiceManager.save_file` to save the file.
save the file.
""" """
default_service_enabled = Settings().value(u'advanced/default service enabled') default_service_enabled = Settings().value(u'advanced/default service enabled')
if default_service_enabled: if default_service_enabled:
@ -646,8 +639,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
default_file_name = u'' default_file_name = u''
directory = Settings().value(self.main_window.service_manager_settings_section + u'/last directory') directory = Settings().value(self.main_window.service_manager_settings_section + u'/last directory')
path = os.path.join(directory, default_file_name) path = os.path.join(directory, default_file_name)
# SaveAs from osz to oszl is not valid as the files will be deleted # SaveAs from osz to oszl is not valid as the files will be deleted on exit which is not sensible or usable in
# on exit which is not sensible or usable in the long term. # the long term.
if self._file_name.endswith(u'oszl') or self.service_has_all_original_files: if self._file_name.endswith(u'oszl') or self.service_has_all_original_files:
file_name = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path, file_name = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path,
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
@ -765,9 +758,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def load_Last_file(self): def load_Last_file(self):
""" """
Load the last service item from the service manager when the Load the last service item from the service manager when the service was last closed. Can be blank if there was
service was last closed. Can be blank if there was no service no service present.
present.
""" """
file_name = Settings().value(u'servicemanager/last file') file_name = Settings().value(u'servicemanager/last file')
if file_name: if file_name:
@ -799,7 +791,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
self.notes_action.setVisible(True) self.notes_action.setVisible(True)
if service_item[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \ if service_item[u'service_item'].is_capable(ItemCapabilities.CanLoop) and \
len(service_item[u'service_item'].get_frames()) > 1: len(service_item[u'service_item'].get_frames()) > 1:
self.auto_play_slides_group.menuAction().setVisible(True) self.auto_play_slides_menu.menuAction().setVisible(True)
self.auto_play_slides_once.setChecked(service_item[u'service_item'].auto_play_slides_once) self.auto_play_slides_once.setChecked(service_item[u'service_item'].auto_play_slides_once)
self.auto_play_slides_loop.setChecked(service_item[u'service_item'].auto_play_slides_loop) self.auto_play_slides_loop.setChecked(service_item[u'service_item'].auto_play_slides_loop)
self.timed_slide_interval.setChecked(service_item[u'service_item'].timed_slide_interval > 0) self.timed_slide_interval.setChecked(service_item[u'service_item'].timed_slide_interval > 0)
@ -811,7 +803,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix) translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix)
# TODO for future: make group explains itself more visually # TODO for future: make group explains itself more visually
else: else:
self.auto_play_slides_group.menuAction().setVisible(False) self.auto_play_slides_menu.menuAction().setVisible(False)
if service_item[u'service_item'].is_capable(ItemCapabilities.HasVariableStartTime): if service_item[u'service_item'].is_capable(ItemCapabilities.HasVariableStartTime):
self.time_action.setVisible(True) self.time_action.setVisible(True)
if service_item[u'service_item'].is_capable(ItemCapabilities.CanAutoStartForLive): if service_item[u'service_item'].is_capable(ItemCapabilities.CanAutoStartForLive):
@ -861,8 +853,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def toggle_auto_play_slides_once(self): def toggle_auto_play_slides_once(self):
""" """
Toggle Auto play slide once. Toggle Auto play slide once. Inverts auto play once option for the item
Inverts auto play once option for the item
""" """
item = self.find_service_item()[0] item = self.find_service_item()[0]
service_item = self.service_items[item][u'service_item'] service_item = self.service_items[item][u'service_item']
@ -923,8 +914,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def on_service_item_edit_form(self): def on_service_item_edit_form(self):
""" """
Opens a dialog to edit the service item and update the service Opens a dialog to edit the service item and update the service display if changes are saved.
display if changes are saved.
""" """
item = self.find_service_item()[0] item = self.find_service_item()[0]
self.service_item_edit_form.set_service_item(self.service_items[item][u'service_item']) self.service_item_edit_form.set_service_item(self.service_items[item][u'service_item'])
@ -934,17 +924,14 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def preview_live(self, unique_identifier, row): def preview_live(self, unique_identifier, row):
""" """
Called by the SlideController to request a preview item be made live Called by the SlideController to request a preview item be made live and allows the next preview to be updated
and allows the next preview to be updated if relevant. if relevant.
``unique_identifier`` ``unique_identifier``
Reference to the service_item Reference to the service_item
``row`` ``row``
individual row number individual row number
""" """
for sitem in self.service_items: for sitem in self.service_items:
if sitem[u'service_item'].unique_identifier == unique_identifier: if sitem[u'service_item'].unique_identifier == unique_identifier:
@ -1022,8 +1009,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def on_move_selection_up(self): def on_move_selection_up(self):
""" """
Moves the cursor selection up the window. Moves the cursor selection up the window. Called by the up arrow.
Called by the up arrow.
""" """
item = self.service_manager_list.currentItem() item = self.service_manager_list.currentItem()
itemBefore = self.service_manager_list.itemAbove(item) itemBefore = self.service_manager_list.itemAbove(item)
@ -1033,8 +1019,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def on_move_selection_down(self): def on_move_selection_down(self):
""" """
Moves the cursor selection down the window. Moves the cursor selection down the window. Called by the down arrow.
Called by the down arrow.
""" """
item = self.service_manager_list.currentItem() item = self.service_manager_list.currentItem()
itemAfter = self.service_manager_list.itemBelow(item) itemAfter = self.service_manager_list.itemBelow(item)
@ -1052,8 +1037,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def collapsed(self, item): def collapsed(self, item):
""" """
Record if an item is collapsed. Used when repainting the list to get the Record if an item is collapsed. Used when repainting the list to get the correct state.
correct state.
""" """
pos = item.data(0, QtCore.Qt.UserRole) pos = item.data(0, QtCore.Qt.UserRole)
self.service_items[pos - 1][u'expanded'] = False self.service_items[pos - 1][u'expanded'] = False
@ -1068,8 +1052,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def expanded(self, item): def expanded(self, item):
""" """
Record if an item is collapsed. Used when repainting the list to get the Record if an item is collapsed. Used when repainting the list to get the correct state.
correct state.
""" """
pos = item.data(0, QtCore.Qt.UserRole) pos = item.data(0, QtCore.Qt.UserRole)
self.service_items[pos - 1][u'expanded'] = True self.service_items[pos - 1][u'expanded'] = True
@ -1134,9 +1117,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def repaint_service_list(self, service_item, service_item_child): def repaint_service_list(self, service_item, service_item_child):
""" """
Clear the existing service list and prepaint all the items. This is Clear the existing service list and prepaint all the items. This is used when moving items as the move takes
used when moving items as the move takes place in a supporting list, place in a supporting list, and when regenerating all the items due to theme changes.
and when regenerating all the items due to theme changes.
``service_item`` ``service_item``
The item which changed. (int) The item which changed. (int)
@ -1234,8 +1216,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def theme_change(self): def theme_change(self):
""" """
The theme may have changed in the settings dialog so make The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
sure the theme combo box is in the correct state.
""" """
log.debug(u'theme_change') log.debug(u'theme_change')
visible = self.renderer.theme_level == ThemeLevel.Global visible = self.renderer.theme_level == ThemeLevel.Global
@ -1244,8 +1225,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def regenerate_service_Items(self, changed=False): def regenerate_service_Items(self, changed=False):
""" """
Rebuild the service list as things have changed and a Rebuild the service list as things have changed and a repaint is the easiest way to do this.
repaint is the easiest way to do this.
""" """
self.application.set_busy_cursor() self.application.set_busy_cursor()
log.debug(u'regenerate_service_Items') log.debug(u'regenerate_service_Items')
@ -1273,8 +1253,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
for item in tempServiceItems: for item in tempServiceItems:
self.add_service_item(item[u'service_item'], False, expand=item[u'expanded'], repaint=False, self.add_service_item(item[u'service_item'], False, expand=item[u'expanded'], repaint=False,
selected=item[u'selected']) selected=item[u'selected'])
# Set to False as items may have changed rendering # Set to False as items may have changed rendering does not impact the saved song so True may also be valid
# does not impact the saved song so True may also be valid
if changed: if changed:
self.set_modified() self.set_modified()
# Repaint it once only at the end # Repaint it once only at the end
@ -1283,8 +1262,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def service_item_update(self, edit_id, unique_identifier, temporary=False): def service_item_update(self, edit_id, unique_identifier, temporary=False):
""" """
Triggered from plugins to update service items. Triggered from plugins to update service items. Save the values as they will be used as part of the service load
Save the values as they will be used as part of the service load
""" """
self.load_item_unique_identifier = unique_identifier self.load_item_unique_identifier = unique_identifier
self.load_item_edit_id = int(edit_id) self.load_item_edit_id = int(edit_id)
@ -1292,8 +1270,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def replace_service_item(self, newItem): def replace_service_item(self, newItem):
""" """
Using the service item passed replace the one with the same edit id Using the service item passed replace the one with the same edit id if found.
if found.
""" """
for item_count, item in enumerate(self.service_items): for item_count, item in enumerate(self.service_items):
if item[u'service_item'].edit_id == newItem.edit_id and item[u'service_item'].name == newItem.name: if item[u'service_item'].edit_id == newItem.edit_id and item[u'service_item'].name == newItem.name:
@ -1376,8 +1353,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def on_make_live(self): def on_make_live(self):
""" """
Send the current item to the Live slide controller but triggered Send the current item to the Live slide controller but triggered by a tablewidget click event.
by a tablewidget click event.
""" """
self.make_live() self.make_live()
@ -1386,8 +1362,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
Send the current item to the Live slide controller Send the current item to the Live slide controller
``row`` ``row``
Row number to be displayed if from preview. Row number to be displayed if from preview. -1 is passed if the value is not set
-1 is passed if the value is not set
""" """
item, child = self.find_service_item() item, child = self.find_service_item()
# No items in service # No items in service
@ -1405,7 +1380,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
self.preview_controller.addServiceManagerItem(self.service_items[item][u'service_item'], 0) self.preview_controller.addServiceManagerItem(self.service_items[item][u'service_item'], 0)
next_item = self.service_manager_list.topLevelItem(item) next_item = self.service_manager_list.topLevelItem(item)
self.service_manager_list.setCurrentItem(next_item) self.service_manager_list.setCurrentItem(next_item)
self.live_controller.previewListWidget.setFocus() self.live_controller.preview_list_widget.setFocus()
else: else:
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'), critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
@ -1432,10 +1407,9 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def find_service_item(self): def find_service_item(self):
""" """
Finds the first selected ServiceItem in the list and returns the Finds the first selected ServiceItem in the list and returns the position of the serviceitem and its selected
position of the serviceitem and its selected child item. For example, child item. For example, if the third child item (in the Slidecontroller known as slide) in the second service
if the third child item (in the Slidecontroller known as slide) in the item is selected this will return::
second service item is selected this will return::
(1, 2) (1, 2)
""" """
@ -1457,8 +1431,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
def drop_event(self, event): def drop_event(self, event):
""" """
Receive drop event and trigger an internal event to get the Receive drop event and trigger an internal event to get the plugins to build and push the correct service item.
plugins to build and push the correct service item
The drag event payload carries the plugin name The drag event payload carries the plugin name
``event`` ``event``
@ -1530,8 +1503,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
theme_group = QtGui.QActionGroup(self.theme_menu) theme_group = QtGui.QActionGroup(self.theme_menu)
theme_group.setExclusive(True) theme_group.setExclusive(True)
theme_group.setObjectName(u'theme_group') theme_group.setObjectName(u'theme_group')
# Create a "Default" theme, which allows the user to reset the item's # Create a "Default" theme, which allows the user to reset the item's theme to the service theme or global
# theme to the service theme or global theme. # theme.
defaultTheme = create_widget_action(self.theme_menu, text=UiStrings().Default, checked=False, defaultTheme = create_widget_action(self.theme_menu, text=UiStrings().Default, checked=False,
triggers=self.on_theme_change_action) triggers=self.on_theme_change_action)
self.theme_menu.setDefaultAction(defaultTheme) self.theme_menu.setDefaultAction(defaultTheme)

View File

@ -118,31 +118,6 @@ class MediaPlugin(Plugin):
""" """
return self.media_controller.get_media_display_html() return self.media_controller.get_media_display_html()
def app_startup(self):
"""
Do a couple of things when the app starts up. In this particular case
we want to check if we have the old "Use Phonon" setting, and convert
it to "enable Phonon" and "make it the first one in the list".
"""
Plugin.app_startup(self)
settings = Settings()
settings.beginGroup(self.settings_section)
if settings.contains(u'use phonon'):
log.info(u'Found old Phonon setting')
players = self.media_controller.mediaPlayers.keys()
has_phonon = u'phonon' in players
if settings.value(u'use phonon') and has_phonon:
log.debug(u'Converting old setting to new setting')
new_players = []
if players:
new_players = [player for player in players if player != u'phonon']
new_players.insert(0, u'phonon')
self.media_controller.mediaPlayers[u'phonon'].is_active = True
settings.setValue(u'players', u','.join(new_players))
self.settingsTab.load()
settings.remove(u'use phonon')
settings.endGroup()
def _get_media_controller(self): def _get_media_controller(self):
""" """
Adds the media controller to the class dynamically Adds the media controller to the class dynamically

View File

@ -18,7 +18,6 @@
<file>author_maintenance.png</file> <file>author_maintenance.png</file>
<file>topic_maintenance.png</file> <file>topic_maintenance.png</file>
<file>song_author_edit.png</file> <file>song_author_edit.png</file>
<file>song_topic_edit.png</file>
<file>song_book_edit.png</file> <file>song_book_edit.png</file>
</qresource> </qresource>
<qresource prefix="images"> <qresource prefix="images">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 KiB

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -47,8 +47,7 @@ mv openlp/core/resources.py openlp/core/resources.py.old
pyrcc4 -o openlp/core/resources.py.new resources/images/openlp-2.qrc pyrcc4 -o openlp/core/resources.py.new resources/images/openlp-2.qrc
# Remove patch breaking lines # Remove patch breaking lines
cat openlp/core/resources.py.new | sed '/# Created: /d;/# by: /d' \ cat openlp/core/resources.py.new | sed '/# Created: /d;/# by: /d' > openlp/core/resources.py
> openlp/core/resources.py
# Patch resources.py to OpenLP coding style # Patch resources.py to OpenLP coding style
patch --posix -s openlp/core/resources.py scripts/resources.patch patch --posix -s openlp/core/resources.py scripts/resources.patch

View File

@ -3,11 +3,11 @@
""" """
from unittest import TestCase from unittest import TestCase
from mock import MagicMock, patch from mock import MagicMock, Mock, patch
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import Registry, ScreenList from openlp.core.lib import Registry, ScreenList, ServiceItem
from openlp.core.ui.mainwindow import MainWindow from openlp.core.ui.mainwindow import MainWindow
@ -42,3 +42,44 @@ class TestServiceManager(TestCase):
# THEN the count of items should be zero # THEN the count of items should be zero
self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0, self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0,
u'The service manager list should be empty ') u'The service manager list should be empty ')
def context_menu_test(self):
"""
Test the context_menu() method.
"""
# GIVEN: A service item added
with patch(u'PyQt4.QtGui.QTreeWidget.itemAt') as mocked_item_at_method, \
patch(u'PyQt4.QtGui.QWidget.mapToGlobal') as mocked_map_to_global, \
patch(u'PyQt4.QtGui.QMenu.exec_') as mocked_exec:
mocked_item = MagicMock()
mocked_item.parent.return_value = None
mocked_item_at_method.return_value = mocked_item
# We want 1 to be returned for the position
mocked_item.data.return_value = 1
# A service item without capabilities.
service_item = ServiceItem()
self.service_manager.service_items = [{u'service_item': service_item}]
q_point = None
# Mocked actions.
self.service_manager.edit_action.setVisible = Mock()
self.service_manager.create_custom_action.setVisible = Mock()
self.service_manager.maintain_action.setVisible = Mock()
self.service_manager.notes_action.setVisible = Mock()
self.service_manager.time_action.setVisible = Mock()
self.service_manager.auto_start_action.setVisible = Mock()
# WHEN: Show the context menu.
self.service_manager.context_menu(q_point)
# THEN: The following actions should be not visible.
self.service_manager.edit_action.setVisible.assert_called_once_with(False), \
u'The action should be set invisible.'
self.service_manager.create_custom_action.setVisible.assert_called_once_with(False), \
u'The action should be set invisible.'
self.service_manager.maintain_action.setVisible.assert_called_once_with(False), \
u'The action should be set invisible.'
self.service_manager.notes_action.setVisible.assert_called_with(True), u'The action should be set visible.'
self.service_manager.time_action.setVisible.assert_called_once_with(False), \
u'The action should be set invisible.'
self.service_manager.auto_start_action.setVisible.assert_called_once_with(False), \
u'The action should be set invisible.'

View File

@ -1,5 +1,5 @@
""" """
Module to test the custom edit form. Module to test the EditCustomForm.
""" """
from unittest import TestCase from unittest import TestCase
from mock import MagicMock, patch from mock import MagicMock, patch
@ -12,7 +12,7 @@ from openlp.plugins.custom.lib.mediaitem import CustomMediaItem
from openlp.plugins.custom.forms.editcustomform import EditCustomForm from openlp.plugins.custom.forms.editcustomform import EditCustomForm
class TestCustomFrom(TestCase): class TestEditCustomForm(TestCase):
""" """
Test the EditCustomForm. Test the EditCustomForm.
""" """

View File

@ -0,0 +1,67 @@
"""
Module to test the EditCustomSlideForm.
"""
from unittest import TestCase
from mock import MagicMock, patch
from PyQt4 import QtGui
from openlp.core.lib import Registry
from openlp.plugins.custom.forms.editcustomslideform import EditCustomSlideForm
class TestEditCustomSlideForm(TestCase):
"""
Test the EditCustomSlideForm.
"""
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.app = QtGui.QApplication([])
self.main_window = QtGui.QMainWindow()
Registry().register(u'main_window', self.main_window)
self.form = EditCustomSlideForm()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
del self.main_window
del self.app
def basic_test(self):
"""
Test if the dialog is correctly set up.
"""
# GIVEN: A mocked QDialog.exec_() method
with patch(u'PyQt4.QtGui.QDialog.exec_') as mocked_exec:
# WHEN: Show the dialog.
self.form.exec_()
# THEN: The dialog should be empty.
assert self.form.slide_text_edit.toPlainText() == u'', u'There should not be any text in the text editor.'
def set_text_test(self):
"""
Test the set_text() method.
"""
# GIVEN: A mocked QDialog.exec_() method
with patch(u'PyQt4.QtGui.QDialog.exec_') as mocked_exec:
mocked_set_focus = MagicMock()
self.form.slide_text_edit.setFocus = mocked_set_focus
wanted_text = u'THIS TEXT SHOULD BE SHOWN.'
# WHEN: Show the dialog and set the text.
self.form.exec_()
self.form.set_text(wanted_text)
# THEN: The dialog should show the text.
assert self.form.slide_text_edit.toPlainText() == wanted_text, \
u'The text editor should show the correct text.'
# THEN: The dialog should have focus.
mocked_set_focus.assert_called_with()