From 24041c7f17a7b772a30ac91744ccf33e850aabbf Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 11 Oct 2012 23:03:54 +0100 Subject: [PATCH 01/12] Presentation error traps --- .../presentations/lib/impresscontroller.py | 4 ++ .../presentations/lib/messagelistener.py | 50 ++++++++++++++++--- .../presentations/lib/powerpointcontroller.py | 6 ++- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index a85f43592..ceb793cb2 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -155,6 +155,8 @@ class ImpressController(PresentationController): desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') except AttributeError: log.warn(u'Failure to find desktop - Impress may have closed') + except pywintypes.com_error: + log.warn(u'Failure to find desktop - Impress may have closed') return desktop if desktop else None def get_com_servicemanager(self): @@ -284,6 +286,8 @@ class ImpressDocument(PresentationDocument): props = tuple(props) doc = self.document pages = doc.getDrawPages() + if not pages: + return if not os.path.isdir(self.get_temp_folder()): os.makedirs(self.get_temp_folder()) for idx in range(pages.getCount()): diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index cb8f7b7b8..dc8ac79d1 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -88,29 +88,40 @@ class Controller(object): Use the last slide number. """ log.debug(u'Live = %s, activate' % self.is_live) + if not self.doc: + return False if self.doc.is_active(): - return + return True if not self.doc.is_loaded(): if not self.doc.load_presentation(): - return + log.warn(u'Failed to activate %s' % self.doc.filepath) + return False if self.is_live: self.doc.start_presentation() if self.doc.slidenumber > 1: if self.doc.slidenumber > self.doc.get_slide_count(): self.doc.slidenumber = self.doc.get_slide_count() self.doc.goto_slide(self.doc.slidenumber) + if self.doc.is_active(): + return True + else: + log.warn(u'Failed to activate %s' % self.doc.filepath) + return False def slide(self, slide): """ Go to a specific slide """ log.debug(u'Live = %s, slide' % self.is_live) + if not self.doc: + return if not self.is_live: return if self.doc.is_blank(): self.doc.slidenumber = int(slide) + 1 return - self.activate() + if not self.activate(): + return self.doc.goto_slide(int(slide) + 1) self.doc.poll_slidenumber(self.is_live) @@ -119,12 +130,15 @@ class Controller(object): Based on the handler passed at startup triggers the first slide """ log.debug(u'Live = %s, first' % self.is_live) + if not self.doc: + return if not self.is_live: return if self.doc.is_blank(): self.doc.slidenumber = 1 return - self.activate() + if not self.activate(): + return self.doc.start_presentation() self.doc.poll_slidenumber(self.is_live) @@ -133,12 +147,15 @@ class Controller(object): Based on the handler passed at startup triggers the last slide """ log.debug(u'Live = %s, last' % self.is_live) + if not self.doc: + return if not self.is_live: return if self.doc.is_blank(): self.doc.slidenumber = self.doc.get_slide_count() return - self.activate() + if not self.activate(): + return self.doc.goto_slide(self.doc.get_slide_count()) self.doc.poll_slidenumber(self.is_live) @@ -147,6 +164,8 @@ class Controller(object): Based on the handler passed at startup triggers the next slide event """ log.debug(u'Live = %s, next' % self.is_live) + if not self.doc: + return if not self.is_live: return if self.doc.is_blank(): @@ -158,7 +177,8 @@ class Controller(object): # contain animations that need to be stepped through. if self.doc.slidenumber > self.doc.get_slide_count(): return - self.activate() + if not self.activate(): + return self.doc.next_step() self.doc.poll_slidenumber(self.is_live) @@ -167,13 +187,16 @@ class Controller(object): Based on the handler passed at startup triggers the previous slide event """ log.debug(u'Live = %s, previous' % self.is_live) + if not self.doc: + return if not self.is_live: return if self.doc.is_blank(): if self.doc.slidenumber > 1: self.doc.slidenumber = self.doc.slidenumber - 1 return - self.activate() + if not self.activate(): + return self.doc.previous_step() self.doc.poll_slidenumber(self.is_live) @@ -182,6 +205,8 @@ class Controller(object): Based on the handler passed at startup triggers slide show to shut down """ log.debug(u'Live = %s, shutdown' % self.is_live) + if not self.doc: + return self.doc.close_presentation() self.doc = None @@ -190,6 +215,8 @@ class Controller(object): Instruct the controller to blank the presentation """ log.debug(u'Live = %s, blank' % self.is_live) + if not self.doc: + return if not self.is_live: return if not self.doc.is_loaded(): @@ -205,6 +232,8 @@ class Controller(object): Instruct the controller to stop and hide the presentation """ log.debug(u'Live = %s, stop' % self.is_live) + if not self.doc: + return if not self.is_live: return if not self.doc.is_loaded(): @@ -218,9 +247,12 @@ class Controller(object): Instruct the controller to unblank the presentation """ log.debug(u'Live = %s, unblank' % self.is_live) + if not self.doc: + return if not self.is_live: return - self.activate() + if not self.activate(): + return if self.doc.slidenumber and \ self.doc.slidenumber != self.doc.get_slide_number(): self.doc.goto_slide(self.doc.slidenumber) @@ -228,6 +260,8 @@ class Controller(object): Receiver.send_message(u'live_display_hide', HideMode.Screen) def poll(self): + if not self.doc: + return self.doc.poll_slidenumber(self.is_live) diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 54b9c2144..63183e7b5 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -94,9 +94,9 @@ class PowerpointController(PresentationController): self.docs[0].close_presentation() if self.process is None: return - if self.process.Presentations.Count > 0: - return try: + if self.process.Presentations.Count > 0: + return self.process.Quit() except pywintypes.com_error: pass @@ -253,6 +253,8 @@ class PowerpointDocument(PresentationDocument): renderer = self.controller.plugin.renderer rect = renderer.screens.current[u'size'] ppt_window = self.presentation.SlideShowSettings.Run() + if not ppt_window: + return ppt_window.Top = rect.y() * 72 / dpi ppt_window.Height = rect.height() * 72 / dpi ppt_window.Left = rect.x() * 72 / dpi From efef105c3facf0e02bb39202a846581b08321eb1 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 12 Oct 2012 20:15:36 +0100 Subject: [PATCH 02/12] ppt problems --- openlp/plugins/presentations/lib/powerpointcontroller.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 63183e7b5..c00c6d559 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -210,6 +210,13 @@ class PowerpointDocument(PresentationDocument): self.presentation.SlideShowSettings.Run() self.presentation.SlideShowWindow.View.State = 1 self.presentation.SlideShowWindow.Activate() + if self.presentation.Application.Version == u'14.0': + # Unblanking is broken in PowerPoint 2010, need to redisplay + slide = self.presentation.SlideShowWindow.View.CurrentShowPosition + click = self.presentation.SlideShowWindow.View.GetClickIndex() + self.presentation.SlideShowWindow.View.GotoSlide(slide) + if click: + self.presentation.SlideShowWindow.View.GotoClick(click) def blank_screen(self): """ From c7e555e0e8660d71ae1edece85f981f9c807c32f Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 12 Oct 2012 22:33:10 +0100 Subject: [PATCH 03/12] Various end of show issues --- openlp/plugins/presentations/lib/impresscontroller.py | 10 ++++++++-- .../plugins/presentations/lib/powerpointcontroller.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index ceb793cb2..b1c0bcc82 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -363,7 +363,9 @@ class ImpressDocument(PresentationDocument): log.debug(u'is active OpenOffice') if not self.is_loaded(): return False - return self.control is not None + if not self.control: + return False + return self.control.isRunning() def unblank_screen(self): """ @@ -384,7 +386,7 @@ class ImpressDocument(PresentationDocument): Returns true if screen is blank """ log.debug(u'is blank OpenOffice') - if self.control: + if self.control and self.control.isRunning(): return self.control.isPaused() else: return False @@ -440,7 +442,11 @@ class ImpressDocument(PresentationDocument): """ Triggers the next effect of slide on the running presentation """ + is_paused = self.control.isPaused() self.control.gotoNextEffect() + time.sleep(0.1) + if not is_paused and self.control.isPaused(): + self.control.gotoPreviousEffect() def previous_step(self): """ diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index c00c6d559..7da9a95d7 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -295,6 +295,8 @@ class PowerpointDocument(PresentationDocument): """ log.debug(u'next_step') self.presentation.SlideShowWindow.View.Next() + if self.get_slide_number() > self.get_slide_count(): + self.previous_step() def previous_step(self): """ From 0ddeef9d8ff19218e27b9d111918b9622819cea6 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 12 Oct 2012 23:13:58 +0100 Subject: [PATCH 04/12] Blank desktop issues --- .../presentations/lib/messagelistener.py | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index dc8ac79d1..fdceda4ab 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -49,6 +49,7 @@ class Controller(object): """ self.is_live = live self.doc = None + self.hide_mode = None log.info(u'%s controller loaded' % live) def add_handler(self, controller, file, hide_mode, slide_no): @@ -67,6 +68,7 @@ class Controller(object): # Inform slidecontroller that the action failed? return self.doc.slidenumber = slide_no + self.hide_mode = hide_mode if self.is_live: if hide_mode == HideMode.Screen: Receiver.send_message(u'live_display_hide', HideMode.Screen) @@ -117,7 +119,7 @@ class Controller(object): return if not self.is_live: return - if self.doc.is_blank(): + if self.hide_mode: self.doc.slidenumber = int(slide) + 1 return if not self.activate(): @@ -134,7 +136,7 @@ class Controller(object): return if not self.is_live: return - if self.doc.is_blank(): + if self.hide_mode: self.doc.slidenumber = 1 return if not self.activate(): @@ -151,7 +153,7 @@ class Controller(object): return if not self.is_live: return - if self.doc.is_blank(): + if self.hide_mode: self.doc.slidenumber = self.doc.get_slide_count() return if not self.activate(): @@ -168,7 +170,7 @@ class Controller(object): return if not self.is_live: return - if self.doc.is_blank(): + if self.hide_mode: if self.doc.slidenumber < self.doc.get_slide_count(): self.doc.slidenumber = self.doc.slidenumber + 1 return @@ -191,7 +193,7 @@ class Controller(object): return if not self.is_live: return - if self.doc.is_blank(): + if self.hide_mode: if self.doc.slidenumber > 1: self.doc.slidenumber = self.doc.slidenumber - 1 return @@ -215,23 +217,28 @@ class Controller(object): Instruct the controller to blank the presentation """ log.debug(u'Live = %s, blank' % self.is_live) + self.hide_mode = hide_mode if not self.doc: return if not self.is_live: return - if not self.doc.is_loaded(): - return - if not self.doc.is_active(): - return if hide_mode == HideMode.Theme: + if not self.doc.is_loaded(): + return + if not self.doc.is_active(): + return Receiver.send_message(u'live_display_hide', HideMode.Theme) - self.doc.blank_screen() + elif hide_mode == HideMode.Blank: + if not self.activate(): + return + self.doc.blank_screen() def stop(self): """ Instruct the controller to stop and hide the presentation """ log.debug(u'Live = %s, stop' % self.is_live) + self.hide_mode = HideMode.Screen if not self.doc: return if not self.is_live: @@ -247,6 +254,7 @@ class Controller(object): Instruct the controller to unblank the presentation """ log.debug(u'Live = %s, unblank' % self.is_live) + self.hide_mode = None if not self.doc: return if not self.is_live: From 4c1fe14fd2f018292eb15e2eff05c96fb94a86e6 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 13 Oct 2012 19:32:32 +0100 Subject: [PATCH 05/12] Raoul's kicks --- openlp/plugins/presentations/lib/impresscontroller.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index b1c0bcc82..3d78f7bdb 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -153,9 +153,7 @@ class ImpressController(PresentationController): desktop = None try: desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') - except AttributeError: - log.warn(u'Failure to find desktop - Impress may have closed') - except pywintypes.com_error: + except (AttributeError, pywintypes.com_error): log.warn(u'Failure to find desktop - Impress may have closed') return desktop if desktop else None @@ -363,9 +361,7 @@ class ImpressDocument(PresentationDocument): log.debug(u'is active OpenOffice') if not self.is_loaded(): return False - if not self.control: - return False - return self.control.isRunning() + return self.control.isRunning() if self.control else False def unblank_screen(self): """ From 9f5ed9589bdd08ab4361f540275ba1901f028441 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 13 Oct 2012 20:07:30 +0100 Subject: [PATCH 06/12] Slide counts can only be got if active --- openlp/plugins/presentations/lib/messagelistener.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index fdceda4ab..bf46191ac 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -171,16 +171,18 @@ class Controller(object): if not self.is_live: return if self.hide_mode: + if not self.doc.is_active(): + return if self.doc.slidenumber < self.doc.get_slide_count(): self.doc.slidenumber = self.doc.slidenumber + 1 return + if not self.activate(): + return # The "End of slideshow" screen is after the last slide # Note, we can't just stop on the last slide, since it may # contain animations that need to be stepped through. if self.doc.slidenumber > self.doc.get_slide_count(): return - if not self.activate(): - return self.doc.next_step() self.doc.poll_slidenumber(self.is_live) @@ -194,6 +196,8 @@ class Controller(object): if not self.is_live: return if self.hide_mode: + if not self.doc.is_active(): + return if self.doc.slidenumber > 1: self.doc.slidenumber = self.doc.slidenumber - 1 return From bbbf426cf2a9c19a5d6632f259bf40acfd8c69ae Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 13 Oct 2012 20:48:58 +0100 Subject: [PATCH 07/12] If change slides whilst blank, update slidecontroller --- .../presentations/lib/messagelistener.py | 19 ++++++++++++------- .../lib/presentationcontroller.py | 11 ++++++----- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index bf46191ac..7cc12c7f9 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -80,7 +80,7 @@ class Controller(object): else: self.doc.start_presentation() Receiver.send_message(u'live_display_hide', HideMode.Screen) - self.doc.slidenumber = 0 + self.doc.slidenumber = 1 if slide_no > 1: self.slide(slide_no) @@ -121,11 +121,12 @@ class Controller(object): return if self.hide_mode: self.doc.slidenumber = int(slide) + 1 + self.poll() return if not self.activate(): return self.doc.goto_slide(int(slide) + 1) - self.doc.poll_slidenumber(self.is_live) + self.poll() def first(self): """ @@ -138,11 +139,12 @@ class Controller(object): return if self.hide_mode: self.doc.slidenumber = 1 + self.poll() return if not self.activate(): return self.doc.start_presentation() - self.doc.poll_slidenumber(self.is_live) + self.poll() def last(self): """ @@ -155,11 +157,12 @@ class Controller(object): return if self.hide_mode: self.doc.slidenumber = self.doc.get_slide_count() + self.poll() return if not self.activate(): return self.doc.goto_slide(self.doc.get_slide_count()) - self.doc.poll_slidenumber(self.is_live) + self.poll() def next(self): """ @@ -175,6 +178,7 @@ class Controller(object): return if self.doc.slidenumber < self.doc.get_slide_count(): self.doc.slidenumber = self.doc.slidenumber + 1 + self.poll() return if not self.activate(): return @@ -184,7 +188,7 @@ class Controller(object): if self.doc.slidenumber > self.doc.get_slide_count(): return self.doc.next_step() - self.doc.poll_slidenumber(self.is_live) + self.poll() def previous(self): """ @@ -200,11 +204,12 @@ class Controller(object): return if self.doc.slidenumber > 1: self.doc.slidenumber = self.doc.slidenumber - 1 + self.poll() return if not self.activate(): return self.doc.previous_step() - self.doc.poll_slidenumber(self.is_live) + self.poll() def shutdown(self): """ @@ -274,7 +279,7 @@ class Controller(object): def poll(self): if not self.doc: return - self.doc.poll_slidenumber(self.is_live) + self.doc.poll_slidenumber(self.is_live, self.hide_mode) class MessageListener(object): diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index b72e1e9d4..4006cbc3e 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -260,16 +260,17 @@ class PresentationDocument(object): else: return None - def poll_slidenumber(self, is_live): + def poll_slidenumber(self, is_live, hide_mode): """ Check the current slide number """ if not self.is_active(): return - current = self.get_slide_number() - if current == self.slidenumber: - return - self.slidenumber = current + if not hide_mode: + current = self.get_slide_number() + if current == self.slidenumber: + return + self.slidenumber = current if is_live: prefix = u'live' else: From 0f18ec43a060b7f4f7bfe99ddee2bf5d2a4eb583 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sun, 14 Oct 2012 13:11:48 +0200 Subject: [PATCH 08/12] Bug #687638: improved performance of local aware sorting. --- openlp/core/utils/__init__.py | 12 ++++++--- openlp/plugins/songs/forms/songexportform.py | 4 ++- openlp/plugins/songs/lib/db.py | 26 +++++++++++++------- openlp/plugins/songs/lib/mediaitem.py | 5 ++-- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 764cab06a..742b1e4bc 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -498,8 +498,13 @@ def locale_compare(string1, string2): """ # Function locale.strcol() from standard Python library does not work # properly on Windows and probably somewhere else. - return int(QtCore.QString.localeAwareCompare( - QtCore.QString(string1).toLower(), QtCore.QString(string2).toLower())) + return QtCore.QString.localeAwareCompare(string1.lower(), string2.lower()) + + +# For performance reasons provide direct reference to compare function +# without wrapping it in another function making te string lowercase. +# This is needed for sorting songs. +locale_direct_compare = QtCore.QString.localeAwareCompare from languagemanager import LanguageManager @@ -508,4 +513,5 @@ from actions import ActionList __all__ = [u'AppLocation', u'get_application_version', u'check_latest_version', u'add_actions', u'get_filesystem_encoding', u'LanguageManager', u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance', - u'delete_file', u'clean_filename', u'format_time', u'locale_compare'] + u'delete_file', u'clean_filename', u'format_time', u'locale_compare', + u'locale_direct_compare'] diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py index 15239f9c2..1f2988568 100644 --- a/openlp/plugins/songs/forms/songexportform.py +++ b/openlp/plugins/songs/forms/songexportform.py @@ -37,6 +37,7 @@ from openlp.core.lib import build_icon, Receiver, SettingsManager, translate, \ create_separated_list from openlp.core.lib.ui import UiStrings, critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard, WizardStrings +from openlp.core.utils import locale_direct_compare from openlp.plugins.songs.lib.db import Song from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport @@ -251,7 +252,8 @@ class SongExportForm(OpenLPWizard): # Load the list of songs. Receiver.send_message(u'cursor_busy') songs = self.plugin.manager.get_all_objects(Song) - songs.sort() + songs.sort( + cmp=locale_direct_compare, key=lambda song: song.sort_string) for song in songs: # No need to export temporary songs. if song.temporary: diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index 36b6d53ad..122d29859 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -31,11 +31,11 @@ the Songs plugin """ from sqlalchemy import Column, ForeignKey, Table, types -from sqlalchemy.orm import mapper, relation +from sqlalchemy.orm import mapper, relation, reconstructor from sqlalchemy.sql.expression import func +from PyQt4 import QtCore from openlp.core.lib.db import BaseModel, init_db -from openlp.core.utils import locale_compare class Author(BaseModel): """ @@ -64,14 +64,22 @@ class Song(BaseModel): """ Song model """ - # By default sort the songs by its title considering language specific - # characters. - def __lt__(self, other): - r = locale_compare(self.title, other.title) - return True if r < 0 else False + def __init__(self): + self.sort_string = '' - def __eq__(self, other): - return 0 == locale_compare(self.title, other.title) + # This decorator tells sqlalchemy to call this method everytime + # any data on this object are updated. + @reconstructor + def init_on_load(self): + """ + Precompute string to be used for sorting. + + Song sorting is performance sensitive operation. + To get maximum speed lets precompute the string + used for comparison. + """ + # Avoid the overhead of converting string to lowercase and to QString + self.sort_string = QtCore.QString(self.title.lower()) class Topic(BaseModel): diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 0808bcba0..05da69f61 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -39,7 +39,7 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ check_directory_exists from openlp.core.lib.ui import UiStrings, create_widget_action from openlp.core.lib.settings import Settings -from openlp.core.utils import AppLocation +from openlp.core.utils import AppLocation, locale_direct_compare from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ SongImportForm, SongExportForm from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ @@ -259,7 +259,8 @@ class SongMediaItem(MediaManagerItem): log.debug(u'display results Song') self.saveAutoSelectId() self.listView.clear() - searchresults.sort() + searchresults.sort( + cmp=locale_direct_compare, key=lambda song: song.sort_string) for song in searchresults: # Do not display temporary songs if song.temporary: From 7321f5fb2d7cc1c061b3062a2962c9b00c0236ed Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sun, 14 Oct 2012 20:42:20 +0200 Subject: [PATCH 09/12] Bug #1002038: Disable and hide presentation plugin on osx. --- openlp/core/lib/pluginmanager.py | 8 ++++++++ openlp/core/ui/firsttimewizard.py | 20 +++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 8899f5846..b90375506 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -85,6 +85,14 @@ class PluginManager(object): log.debug(u'finding plugins in %s at depth %d', unicode(plugin_dir), startdepth) for root, dirs, files in os.walk(plugin_dir): + # TODO Presentation plugin is not yet working on Mac OS X. + # For now just ignore it. The following code will hide it + # in settings dialog. + if sys.platform == 'darwin': + present_plugin_dir = os.path.join(plugin_dir, 'presentations') + # Ignore files from the presentation plugin directory. + if root.startswith(present_plugin_dir): + continue for name in files: if name.endswith(u'.py') and not name.startswith(u'__'): path = os.path.abspath(os.path.join(root, name)) diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 1ce523cbc..92204a583 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -82,13 +82,13 @@ class Ui_FirstTimeWizard(object): self.imageCheckBox.setChecked(True) self.imageCheckBox.setObjectName(u'imageCheckBox') self.pluginLayout.addWidget(self.imageCheckBox) - self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage) - if sys.platform == "darwin": - self.presentationCheckBox.setChecked(False) - else: + # TODO Presentation plugin is not yet working on Mac OS X. + # For now just ignore it. + if sys.platform != 'darwin': + self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage) self.presentationCheckBox.setChecked(True) - self.presentationCheckBox.setObjectName(u'presentationCheckBox') - self.pluginLayout.addWidget(self.presentationCheckBox) + self.presentationCheckBox.setObjectName(u'presentationCheckBox') + self.pluginLayout.addWidget(self.presentationCheckBox) self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage) self.mediaCheckBox.setChecked(True) self.mediaCheckBox.setObjectName(u'mediaCheckBox') @@ -214,9 +214,11 @@ class Ui_FirstTimeWizard(object): self.bibleCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Bible')) self.imageCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Images')) - self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', - 'Presentations')) - if sys.platform == "darwin": + # TODO Presentation plugin is not yet working on Mac OS X. + # For now just ignore it. + if sys.platform != 'darwin': + self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', + 'Presentations')) self.presentationCheckBox.setEnabled(False) self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Media (Audio and Video)')) From 16c0ec482e5db0fbe0335ec09c9041e60d9b6e88 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Mon, 15 Oct 2012 10:25:42 +0200 Subject: [PATCH 10/12] Bug #1002038: Fix enabling presentation plugin if no osx os. --- openlp/core/ui/firsttimewizard.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 92204a583..4477dd4cb 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -219,7 +219,6 @@ class Ui_FirstTimeWizard(object): if sys.platform != 'darwin': self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Presentations')) - self.presentationCheckBox.setEnabled(False) self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Media (Audio and Video)')) self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard', From f84c0899389cb8444f7615306012935e928af61c Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 16 Oct 2012 10:25:54 +0200 Subject: [PATCH 11/12] fixed bug #1066296 (Renaming theme keeps old/new theme in Theme manager) Fixes: https://launchpad.net/bugs/1066296 --- openlp/core/ui/thememanager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index a5293e3a8..70bf78b29 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -284,6 +284,7 @@ class ThemeManager(QtGui.QWidget): plugin.renameTheme(old_theme_name, new_theme_name) self.mainwindow.renderer.update_theme( new_theme_name, old_theme_name) + self.loadThemes() def onCopyTheme(self): """ From 540fe6fd1bc71202a2dc5c57bea33669273570f3 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 16 Oct 2012 19:21:32 +0100 Subject: [PATCH 12/12] Slow down the Impress start up loop --- openlp/plugins/songs/lib/oooimport.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index 49e6c2a70..da96dc936 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -27,6 +27,7 @@ ############################################################################### import logging import os +import time from PyQt4 import QtCore @@ -123,6 +124,7 @@ class OooImport(SongImport): try: uno_instance = get_uno_instance(resolver) except NoConnectException: + time.sleep(0.1) log.exception("Failed to resolve uno connection") self.startOooProcess() loop += 1