diff --git a/openlp.pyw b/openlp.pyw index 416b2bb13..04f65a5dd 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -184,13 +184,15 @@ class OpenLP(QtGui.QApplication): # make sure Qt really display the splash screen self.processEvents() # start the main app window - self.mainWindow = MainWindow(screens, app_version, self.clipboard(), - not has_run_wizard) + self.mainWindow = MainWindow(screens, app_version, self.clipboard()) self.mainWindow.show() if show_splash: # now kill the splashscreen self.splash.finish(self.mainWindow) self.mainWindow.repaint() + self.processEvents() + if not has_run_wizard: + self.mainWindow.firstTime() update_check = QtCore.QSettings().value( u'general/update check', QtCore.QVariant(True)).toBool() if update_check: diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index b049e2ea7..08e240b5c 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -33,8 +33,7 @@ from ConfigParser import SafeConfigParser from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate, PluginStatus, check_directory_exists, \ - Receiver, build_icon +from openlp.core.lib import translate, PluginStatus, Receiver, build_icon from openlp.core.utils import get_web_page, AppLocation from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage @@ -95,7 +94,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): language = unicode(self.config.get( u'bibles_%s' % lang, u'title'), u'utf8') langItem = QtGui.QTreeWidgetItem( - self.biblesTreeWidget, QtCore.QStringList(language)) + self.biblesTreeWidget, QtCore.QStringList(language)) bibles = self.config.get(u'bibles_%s' % lang, u'translations') bibles = bibles.split(u',') for bible in bibles: @@ -104,24 +103,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): filename = unicode(self.config.get( u'bible_%s' % bible, u'filename')) item = QtGui.QTreeWidgetItem( - langItem, QtCore.QStringList(title)) - item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(filename)) + langItem, QtCore.QStringList(title)) + item.setData(0, QtCore.Qt.UserRole, + QtCore.QVariant(filename)) item.setCheckState(0, QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) self.biblesTreeWidget.expandAll() themes = self.config.get(u'themes', u'files') themes = themes.split(u',') + if not os.path.exists(os.path.join(gettempdir(), u'openlp')): + os.makedirs(os.path.join(gettempdir(), u'openlp')) for theme in themes: title = self.config.get(u'theme_%s' % theme, u'title') filename = self.config.get(u'theme_%s' % theme, u'filename') screenshot = self.config.get(u'theme_%s' % theme, u'screenshot') urllib.urlretrieve(u'%s/%s' % (self.web, screenshot), - os.path.join(gettempdir(), screenshot)) + os.path.join(gettempdir(), u'openlp', screenshot)) item = QtGui.QListWidgetItem(title, self.themesListWidget) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(filename)) item.setIcon(build_icon( - os.path.join(gettempdir(), screenshot))) + os.path.join(gettempdir(), u'openlp', screenshot))) item.setCheckState(QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) @@ -222,7 +224,8 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): 'Enabling selected plugins...')) self._setPluginStatus(self.songsCheckBox, u'songs/status') self._setPluginStatus(self.bibleCheckBox, u'bibles/status') - self._setPluginStatus(self.presentationCheckBox, u'presentations/status') + self._setPluginStatus(self.presentationCheckBox, + u'presentations/status') self._setPluginStatus(self.imageCheckBox, u'images/status') self._setPluginStatus(self.mediaCheckBox, u'media/status') self._setPluginStatus(self.remoteCheckBox, u'remotes/status') @@ -230,29 +233,18 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self._setPluginStatus(self.songUsageCheckBox, u'songusage/status') self._setPluginStatus(self.alertCheckBox, u'alerts/status') # Build directories for downloads - songs_destination = AppLocation.get_section_data_path(u'songs') + songs_destination = os.path.join(unicode(gettempdir()), u'openlp') bibles_destination = AppLocation.get_section_data_path(u'bibles') themes_destination = AppLocation.get_section_data_path(u'themes') - # Install songs + # Download songs for i in xrange(self.songsListWidget.count()): item = self.songsListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: filename = item.data(QtCore.Qt.UserRole).toString() self._incrementProgressBar(self.downloading % filename) - destination = os.path.join(songs_destination, u'songs.sqlite') - if os.path.exists(destination): - if QtGui.QMessageBox.question(self, - translate('OpenLP.FirstTimeWizard', - 'Overwrite Existing Songs?'), - translate('OpenLP.FirstTimeWizard', 'Your songs ' - 'database already exists and your current songs will ' - 'be permanently lost, are you sure you want to ' - 'replace it ?'), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, - QtGui.QMessageBox.No) != QtGui.QMessageBox.Yes: - continue + destination = os.path.join(songs_destination, unicode(filename)) urllib.urlretrieve(u'%s%s' % (self.web, filename), destination) - # Install Bibles + # Download Bibles bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) while bibles_iterator.value(): item = bibles_iterator.value() @@ -262,7 +254,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): urllib.urlretrieve(u'%s%s' % (self.web, bible), os.path.join(bibles_destination, bible)) bibles_iterator += 1 - # Install themes + # Download themes for i in xrange(self.themesListWidget.count()): item = self.themesListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: @@ -285,4 +277,3 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): status = PluginStatus.Active if field.checkState() \ == QtCore.Qt.Checked else PluginStatus.Inactive QtCore.QSettings().setValue(tag, QtCore.QVariant(status)) - diff --git a/openlp/core/ui/firsttimelanguagedialog.py b/openlp/core/ui/firsttimelanguagedialog.py index ae44abeb5..93751763f 100644 --- a/openlp/core/ui/firsttimelanguagedialog.py +++ b/openlp/core/ui/firsttimelanguagedialog.py @@ -46,7 +46,8 @@ class Ui_FirstTimeLanguageDialog(object): self.languageLabel.setObjectName(u'languageLabel') self.languageLayout.addWidget(self.languageLabel) self.languageComboBox = QtGui.QComboBox(languageDialog) - self.languageComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + self.languageComboBox.setSizeAdjustPolicy( + QtGui.QComboBox.AdjustToContents) self.languageComboBox.setObjectName("languageComboBox") self.languageLayout.addWidget(self.languageComboBox) self.dialogLayout.addLayout(self.languageLayout) diff --git a/openlp/core/ui/firsttimelanguageform.py b/openlp/core/ui/firsttimelanguageform.py index a8ce3bd57..22057fbfc 100644 --- a/openlp/core/ui/firsttimelanguageform.py +++ b/openlp/core/ui/firsttimelanguageform.py @@ -26,7 +26,6 @@ from PyQt4 import QtGui -from openlp.core.lib import translate from openlp.core.utils import LanguageManager from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 72ebe422a..79d3890a9 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -67,6 +67,7 @@ class MainDisplay(DisplayWidget): self.isLive = live self.alertTab = None self.hideMode = None + self.videoHide = False self.override = {} mainIcon = build_icon(u':/icon/openlp-logo-16x16.png') self.setWindowIcon(mainIcon) @@ -90,7 +91,7 @@ class MainDisplay(DisplayWidget): """ Set up and build the output screen """ - log.debug(u'Start setup for monitor %s (live = %s)' % + log.debug(u'Start setup for monitor %s (live = %s)' % (self.screens.monitor_number, self.isLive)) self.usePhonon = QtCore.QSettings().value( u'media/use phonon', QtCore.QVariant(True)).toBool() @@ -110,6 +111,12 @@ class MainDisplay(DisplayWidget): QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'), self.videoStart) + QtCore.QObject.connect(self.mediaObject, + QtCore.SIGNAL(u'finished()'), + self.videoFinished) + QtCore.QObject.connect(self.mediaObject, + QtCore.SIGNAL(u'tick(qint64)'), + self.videoTick) log.debug(u'Setup webView for monitor %s' % self.screens.monitor_number) self.webView = QtWebKit.QWebView(self) self.webView.setGeometry(0, 0, @@ -143,24 +150,23 @@ class MainDisplay(DisplayWidget): if not background_color.isValid(): background_color = QtCore.Qt.white splash_image = QtGui.QImage(image_file) - initialFrame = QtGui.QImage( + self.initialFrame = QtGui.QImage( self.screens.current[u'size'].width(), self.screens.current[u'size'].height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + QtGui.QImage.Format_ARGB32_Premultiplied) painter_image = QtGui.QPainter() - painter_image.begin(initialFrame) - painter_image.fillRect(initialFrame.rect(), background_color) + painter_image.begin(self.initialFrame) + painter_image.fillRect(self.initialFrame.rect(), background_color) painter_image.drawImage( (self.screens.current[u'size'].width() - splash_image.width()) / 2, (self.screens.current[u'size'].height() - splash_image.height()) / 2, splash_image) serviceItem = ServiceItem() - serviceItem.bg_image_bytes = image_to_byte(initialFrame) + serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) self.webView.setHtml(build_html(serviceItem, self.screen, self.alertTab, self.isLive, None)) - self.initialFrame = True - self.__hideMouse() + self.__hideMouse() # To display or not to display? if not self.screen[u'primary']: self.show() @@ -181,6 +187,7 @@ class MainDisplay(DisplayWidget): # Wait for the webview to update before displaying text. while not self.webLoaded: Receiver.send_message(u'openlp_process_events') + self.setGeometry(self.screen[u'size']) self.frame.evaluateJavaScript(u'show_text("%s")' % \ slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) return self.preview() @@ -192,7 +199,7 @@ class MainDisplay(DisplayWidget): `slide` The slide text to be displayed """ - log.debug(u'alert to display') + log.debug(u'alert to display') if self.height() != self.screen[u'size'].height() \ or not self.isVisible() or self.videoWidget.isVisible(): shrink = True @@ -208,12 +215,18 @@ class MainDisplay(DisplayWidget): else: shrinkItem = self if text: - shrinkItem.resize(self.width(), int(height.toString())) + alert_height = int(height.toString()) + shrinkItem.resize(self.width(), alert_height) shrinkItem.setVisible(True) + if self.alertTab.location == 1: + shrinkItem.move(self.screen[u'size'].left(), + (self.screen[u'size'].height() - alert_height) / 2) + elif self.alertTab.location == 2: + shrinkItem.move(self.screen[u'size'].left(), + self.screen[u'size'].height() - alert_height) else: shrinkItem.setVisible(False) - shrinkItem.resize(self.screen[u'size'].width(), - self.screen[u'size'].height()) + self.setGeometry(self.screen[u'size']) def directImage(self, name, path): """ @@ -243,6 +256,7 @@ class MainDisplay(DisplayWidget): """ Display an image, as is. """ + self.setGeometry(self.screen[u'size']) if image: js = u'show_image("data:image/png;base64,%s");' % image else: @@ -262,6 +276,7 @@ class MainDisplay(DisplayWidget): self.displayImage(self.serviceItem.bg_image_bytes) else: self.displayImage(None) + # clear the cache self.override = {} # Update the preview frame. if self.isLive: @@ -336,6 +351,7 @@ class MainDisplay(DisplayWidget): """ log.debug(u'video') self.webLoaded = True + self.setGeometry(self.screen[u'size']) # We are running a background theme self.override[u'theme'] = u'' self.override[u'video'] = True @@ -349,6 +365,10 @@ class MainDisplay(DisplayWidget): self.mediaObject.stop() self.mediaObject.clearQueue() self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath)) + # Need the timer to trigger set the trigger to 200ms + # Value taken from web documentation. + if self.serviceItem.start_time != 0: + self.mediaObject.setTickInterval(200) self.mediaObject.play() self.webView.setVisible(False) self.videoWidget.setVisible(True) @@ -363,8 +383,26 @@ class MainDisplay(DisplayWidget): Start the video at a predetermined point. """ if newState == Phonon.PlayingState: + # set start time in milliseconds self.mediaObject.seek(self.serviceItem.start_time * 1000) + def videoFinished(self): + """ + Blank the Video when it has finished so the final frame is not left + hanging + """ + self.videoStop() + self.hideDisplay(HideMode.Blank) + self.phononActive = False + self.videoHide = True + + def videoTick(self, tick): + """ + Triggered on video tick every 200 milli seconds + Will be used to manage stop time later + """ + pass + def isWebLoaded(self): """ Called by webView event to show display is fully loaded @@ -396,7 +434,7 @@ class MainDisplay(DisplayWidget): if self.hideMode: self.hideDisplay(self.hideMode) else: - self.setVisible(True) + self.setVisible(True) preview = QtGui.QImage(self.screen[u'size'].width(), self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) @@ -413,7 +451,7 @@ class MainDisplay(DisplayWidget): """ log.debug(u'buildHtml') self.webLoaded = False - self.initialFrame = False + self.initialFrame = None self.serviceItem = serviceItem background = None # We have an image override so keep the image till the theme changes @@ -422,10 +460,12 @@ class MainDisplay(DisplayWidget): if u'video' in self.override: Receiver.send_message(u'video_background_replaced') self.override = {} + # We have a different theme. elif self.override[u'theme'] != serviceItem.themedata.theme_name: Receiver.send_message(u'live_theme_changed') self.override = {} else: + # replace the background background = self.imageManager. \ get_image_bytes(self.override[u'image']) if self.serviceItem.themedata.background_filename: @@ -441,6 +481,10 @@ class MainDisplay(DisplayWidget): # if was hidden keep it hidden if self.hideMode and self.isLive: self.hideDisplay(self.hideMode) + # display hidden for video end we have a new item so must be shown + if self.videoHide and self.isLive: + self.videoHide = False + self.showDisplay() self.__hideMouse() def footer(self, text): diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index cb324a872..06b809a20 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -25,6 +25,8 @@ ############################################################################### import logging +import os +from tempfile import gettempdir from PyQt4 import QtCore, QtGui @@ -461,14 +463,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): actionList = ActionList() - def __init__(self, screens, applicationVersion, clipboard, firstTime): + def __init__(self, screens, applicationVersion, clipboard): """ This constructor sets up the interface, the various managers, and the plugins. """ QtGui.QMainWindow.__init__(self) self.screens = screens - self.actionList = ActionList() self.applicationVersion = applicationVersion self.clipboard = clipboard # Set up settings sections for the main application @@ -478,6 +479,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.serviceSettingsSection = u'servicemanager' self.songsSettingsSection = u'songs' self.serviceNotSaved = False + self.actionList = ActionList() self.settingsmanager = SettingsManager(screens) self.aboutForm = AboutForm(self, applicationVersion) self.settingsForm = SettingsForm(self.screens, self, self) @@ -624,10 +626,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.MediaToolBox.setCurrentIndex(savedPlugin) self.settingsForm.postSetUp() Receiver.send_message(u'cursor_normal') - # Import themes if first time - if firstTime: - self.themeManagerContents.firstTime() - def setAutoLanguage(self, value): self.LanguageGroup.setDisabled(value) @@ -670,6 +668,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.setViewMode(False, True, False, False, True) self.ModeLiveItem.setChecked(True) + def firstTime(self): + # Import themes if first time + Receiver.send_message(u'openlp_process_events') + self.themeManagerContents.firstTime() + for plugin in self.pluginManager.plugins: + if hasattr(plugin, u'firstTime'): + Receiver.send_message(u'openlp_process_events') + plugin.firstTime() + Receiver.send_message(u'openlp_process_events') + temp_dir = os.path.join(unicode(gettempdir()), u'openlp') + for filename in os.listdir(temp_dir): + os.remove(os.path.join(temp_dir, filename)) + os.removedirs(temp_dir) + def blankCheck(self): """ Check and display message if screen blank on setup. diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 381712977..54b48cdf6 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -391,7 +391,7 @@ def get_uno_command(): Returns the UNO command to launch an openoffice.org instance. """ COMMAND = u'soffice' - OPTIONS = u'-nologo -norestore -minimized -invisible -nofirststartwizard' + OPTIONS = u'-nologo -norestore -minimized -nodefault -nofirststartwizard' if UNO_CONNECTION_TYPE == u'pipe': CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"' else: diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index e2dde59fd..52baab14c 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -227,6 +227,10 @@ class BGExtract(object): cleanup = [(re.compile('\s+'), lambda match: ' ')] verses = BeautifulSoup(str(soup), markupMassage=cleanup) verse_list = {} + # Cater for inconsistent mark up in the first verse of a chapter. + first_verse = verses.find(u'versenum') + if first_verse: + verse_list[1] = unicode(first_verse.contents[0]) for verse in verses(u'sup', u'versenum'): raw_verse_num = verse.next clean_verse_num = 0 diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index dcbad3e63..c11e10588 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -25,14 +25,14 @@ ############################################################################### import logging +import os from PyQt4 import QtCore from openlp.core.lib import Receiver, SettingsManager, translate -from openlp.core.utils import AppLocation +from openlp.core.utils import AppLocation, delete_file from openlp.plugins.bibles.lib import parse_reference from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta - from csvbible import CSVBible from http import HTTPBible from opensong import OpenSongBible @@ -144,6 +144,10 @@ class BibleManager(object): for filename in files: bible = BibleDB(self.parent, path=self.path, file=filename) name = bible.get_name() + # Remove corrupted files. + if name is None: + delete_file(os.path.join(self.path, filename)) + continue log.debug(u'Bible Name: "%s"', name) self.db_cache[name] = bible # Look to see if lazy load bible exists and get create getter. diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 4db78f7a5..6554c033a 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -80,7 +80,8 @@ class Controller(object): if self.doc.is_active(): return if not self.doc.is_loaded(): - self.doc.load_presentation() + if not self.doc.load_presentation(): + return if self.is_live: self.doc.start_presentation() if self.doc.slidenumber > 1: diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 4dc9e8f3a..f220f558a 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -77,8 +77,11 @@ class PowerpointController(PresentationController): """ Loads PowerPoint process """ - self.process = Dispatch(u'PowerPoint.Application') - self.process.Visible = True + log.debug(u'start_process') + if not self.process: + self.process = Dispatch(u'PowerPoint.Application') + if float(self.process.Version) < 13: + self.process.Visible = True self.process.WindowState = 2 def kill(self): @@ -120,13 +123,14 @@ class PowerpointDocument(PresentationDocument): ``presentation`` The file name of the presentations to run. """ - log.debug(u'LoadPresentation') + log.debug(u'load_presentation') if not self.controller.process or not self.controller.process.Visible: self.controller.start_process() try: self.controller.process.Presentations.Open(self.filepath, False, False, True) except pywintypes.com_error: + log.debug(u'PPT open failed') return False self.presentation = self.controller.process.Presentations( self.controller.process.Presentations.Count) @@ -145,6 +149,7 @@ class PowerpointDocument(PresentationDocument): However, for the moment, we want a physical file since it makes life easier elsewhere. """ + log.debug(u'create_thumbnails') if self.check_thumbnails(): return for num in range(0, self.presentation.Slides.Count): @@ -170,6 +175,7 @@ class PowerpointDocument(PresentationDocument): """ Returns ``True`` if a presentation is loaded. """ + log.debug(u'is_loaded') try: if not self.controller.process.Visible: return False @@ -186,6 +192,7 @@ class PowerpointDocument(PresentationDocument): """ Returns ``True`` if a presentation is currently active. """ + log.debug(u'is_active') if not self.is_loaded(): return False try: @@ -201,6 +208,7 @@ class PowerpointDocument(PresentationDocument): """ Unblanks (restores) the presentation. """ + log.debug(u'unblank_screen') self.presentation.SlideShowSettings.Run() self.presentation.SlideShowWindow.View.State = 1 self.presentation.SlideShowWindow.Activate() @@ -209,12 +217,14 @@ class PowerpointDocument(PresentationDocument): """ Blanks the screen. """ + log.debug(u'blank_screen') self.presentation.SlideShowWindow.View.State = 3 def is_blank(self): """ Returns ``True`` if screen is blank. """ + log.debug(u'is_blank') if self.is_active(): return self.presentation.SlideShowWindow.View.State == 3 else: @@ -224,6 +234,7 @@ class PowerpointDocument(PresentationDocument): """ Stops the current presentation and hides the output. """ + log.debug(u'stop_presentation') self.presentation.SlideShowWindow.View.Exit() if os.name == u'nt': @@ -231,6 +242,7 @@ class PowerpointDocument(PresentationDocument): """ Starts a presentation from the beginning. """ + log.debug(u'start_presentation') #SlideShowWindow measures its size/position by points, not pixels try: dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) @@ -253,30 +265,35 @@ class PowerpointDocument(PresentationDocument): """ Returns the current slide number. """ + log.debug(u'get_slide_number') return self.presentation.SlideShowWindow.View.CurrentShowPosition def get_slide_count(self): """ Returns total number of slides. """ + log.debug(u'get_slide_count') return self.presentation.Slides.Count def goto_slide(self, slideno): """ Moves to a specific slide in the presentation. """ + log.debug(u'goto_slide') self.presentation.SlideShowWindow.View.GotoSlide(slideno) def next_step(self): """ Triggers the next effect of slide on the running presentation. """ + log.debug(u'next_step') self.presentation.SlideShowWindow.View.Next() def previous_step(self): """ Triggers the previous slide on the running presentation. """ + log.debug(u'previous_step') self.presentation.SlideShowWindow.View.Previous() def get_slide_text(self, slide_no): diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 0900d1d9d..5ec560167 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -84,7 +84,8 @@ class PptviewController(PresentationController): dllpath = os.path.join(self.plugin.pluginManager.basepath, u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll') self.process = cdll.LoadLibrary(dllpath) - #self.process.SetDebug(1) + if log.isEnabledFor(logging.DEBUG): + self.process.SetDebug(1) def kill(self): """ @@ -140,8 +141,10 @@ class PptviewDocument(PresentationDocument): PPTviewLib creates large BMP's, but we want small PNG's for consistency. Convert them here. """ + log.debug(u'create_thumbnails') if self.check_thumbnails(): return + log.debug(u'create_thumbnails proceeding') for idx in range(self.get_slide_count()): path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), unicode(idx + 1)) diff --git a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py index 1e10def7d..f8d0fabd9 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py +++ b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py @@ -133,7 +133,7 @@ class PPTViewer(QtGui.QWidget): def OpenClick(self): oldid = self.pptid; rect = RECT(100,100,900,700) - filename = unicode(self.PPTEdit.text()) + filename = str(self.PPTEdit.text().replace(u'/', u'\\')) print filename self.pptid = pptdll.OpenPPT(filename, None, rect, 'c:\\temp\\slide') print "id: " + unicode(self.pptid) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index feabc98b7..a07b5091f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -166,20 +166,18 @@ class SongMediaItem(MediaManagerItem): or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ', search_keywords.lower()) + u'%'), Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'), - Song.comments.like(u'%' + search_keywords.lower() + u'%')), - Song.search_title.asc()) + Song.comments.like(u'%' + search_keywords.lower() + u'%'))) self.displayResultsSong(search_results) elif search_type == SongSearch.Titles: log.debug(u'Titles Search') search_results = self.parent.manager.get_all_objects(Song, Song.search_title.like(u'%' + self.whitespace.sub(u' ', - search_keywords.lower()) + u'%'), Song.search_title.asc()) + search_keywords.lower()) + u'%')) self.displayResultsSong(search_results) elif search_type == SongSearch.Lyrics: log.debug(u'Lyrics Search') search_results = self.parent.manager.get_all_objects(Song, - Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'), - Song.search_lyrics.asc()) + Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%')) self.displayResultsSong(search_results) elif search_type == SongSearch.Authors: log.debug(u'Authors Search') @@ -190,7 +188,7 @@ class SongMediaItem(MediaManagerItem): elif search_type == SongSearch.Themes: log.debug(u'Theme Search') search_results = self.parent.manager.get_all_objects(Song, - Song.theme_name == search_keywords, Song.search_lyrics.asc()) + Song.theme_name == search_keywords) self.displayResultsSong(search_results) def onSongListLoad(self): @@ -461,4 +459,5 @@ class SongMediaItem(MediaManagerItem): """ Locale aware collation of song titles """ - return locale.strcoll(unicode(song_1.title), unicode(song_2.title)) + return locale.strcoll(unicode(song_1.title.lower()), + unicode(song_2.title.lower())) diff --git a/openlp/plugins/songs/lib/olpimport.py b/openlp/plugins/songs/lib/olpimport.py index 11170f9a0..9bd098e47 100644 --- a/openlp/plugins/songs/lib/olpimport.py +++ b/openlp/plugins/songs/lib/olpimport.py @@ -151,12 +151,14 @@ class OpenLPSongImport(SongImport): source_songs = self.source_session.query(OldSong).all() song_total = len(source_songs) - self.import_wizard.progressBar.setMaximum(song_total) + if self.import_wizard: + self.import_wizard.progressBar.setMaximum(song_total) song_count = 1 for song in source_songs: - self.import_wizard.incrementProgressBar(unicode(translate( - 'SongsPlugin.OpenLPSongImport', 'Importing song %d of %d.')) % - (song_count, song_total)) + if self.import_wizard: + self.import_wizard.incrementProgressBar( + unicode(translate('SongsPlugin.OpenLPSongImport', + 'Importing song %d of %d.')) % (song_count, song_total)) new_song = Song() new_song.title = song.title if has_media_files and hasattr(song, 'alternate_title'): diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index 49adcd302..37f3136e9 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -33,7 +33,6 @@ import os import re -from songimport import SongImport from oooimport import OooImport if os.name == u'nt': diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 3bc1a082f..4097af636 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -62,6 +62,7 @@ class SongImport(QtCore.QObject): else: raise KeyError(u'Keyword arguments "filename[s]" not supplied.') log.debug(self.import_source) + self.import_wizard = None self.song = None self.stop_import_flag = False self.set_defaults() diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index bd22ea4b2..a59395d65 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -444,7 +444,6 @@ class OpenLyrics(object): """ sxml = SongXML() search_text = u'' - temp_verse_order = [] for verse in lyrics.verse: text = u'' for lines in verse.lines: @@ -455,11 +454,10 @@ class OpenLyrics(object): verse_type_index = VerseType.from_tag(verse_name[0]) verse_type = VerseType.Names[verse_type_index] verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name) - verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:]) - # OpenLyrics allows e. g. "c", but we need "c1". + # OpenLyrics allows e. g. "c", but we need "c1". However, this does + # not correct the verse order. if not verse_number: verse_number = u'1' - temp_verse_order.append((verse_type, verse_number, verse_part)) lang = None if self._get(verse, u'lang'): lang = self._get(verse, u'lang') @@ -470,24 +468,6 @@ class OpenLyrics(object): # Process verse order if hasattr(properties, u'verseOrder'): song.verse_order = self._text(properties.verseOrder) - else: - # We have to process the temp_verse_order, as the verseOrder - # property is not present. - previous_type = u'' - previous_number = u'' - previous_part = u'' - verse_order = [] - # Currently we do not support different "parts"! - for name in temp_verse_order: - if name[0] == previous_type: - if name[1] != previous_number: - verse_order.append(u''.join((name[0][0], name[1]))) - else: - verse_order.append(u''.join((name[0][0], name[1]))) - previous_type = name[0] - previous_number = name[1] - previous_part = name[2] - song.verse_order = u' '.join(verse_order) def _process_songbooks(self, properties, song): """ diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 1e072afdf..bd953ffac 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -26,16 +26,20 @@ import logging import re +import os +from tempfile import gettempdir from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, StringContent, build_icon, translate +from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ + Receiver from openlp.core.lib.db import Manager from openlp.core.lib.ui import UiStrings from openlp.plugins.songs.lib import add_author_unknown, SongMediaItem, \ SongsTab, SongXML from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.importer import SongFormat +from openlp.plugins.songs.lib.olpimport import OpenLPSongImport log = logging.getLogger(__name__) @@ -244,6 +248,35 @@ class SongsPlugin(Plugin): } self.setPluginUiTextStrings(tooltips) + def firstTime(self): + """ + If the first time wizard has run, this function is run to import all the + new songs into the database. + """ + db_dir = unicode(os.path.join(gettempdir(), u'openlp')) + song_dbs = [] + for sfile in os.listdir(db_dir): + if sfile.startswith(u'songs_') and sfile.endswith(u'.sqlite'): + song_dbs.append(os.path.join(db_dir, sfile)) + if len(song_dbs) == 0: + return + progress = QtGui.QProgressDialog(self.formparent) + progress.setWindowModality(QtCore.Qt.WindowModal) + progress.setLabelText(translate('OpenLP.Ui', 'Starting import...')) + progress.setCancelButton(None) + progress.setRange(0, len(song_dbs)) + progress.setMinimumDuration(0) + progress.forceShow() + for idx, db in enumerate(song_dbs): + progress.setValue(idx) + Receiver.send_message(u'openlp_process_events') + importer = OpenLPSongImport(self.manager, filename=db) + importer.do_import() + progress.setValue(len(song_dbs)) + self.mediaItem.displayResultsSong( + self.manager.get_all_objects(Song, order_by_ref=Song.search_title)) + self.onToolsReindexItemTriggered() + def finalise(self): """ Time to tidy up on exit