forked from openlp/openlp
Use the doubleclick-go-live setting in the preview controller. Fixes bug 1422197.
If no copyright info is given for bible, don't print it. Fixes bug 1420785. Make csv-bible import work with python3. Fixes bug 1421136. Add default shortcut bindings for preview next/prev, and make the appear in the shortcut edit dialog. Fixes bug 1412570. bzr-revno: 2502
This commit is contained in:
commit
1b2b1c74cc
@ -216,7 +216,8 @@ class Settings(QtCore.QSettings):
|
||||
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextTrackItem': [],
|
||||
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Down), QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextItem_preview': [],
|
||||
'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
|
||||
'shortcuts/newService': [],
|
||||
'shortcuts/offlineHelpItem': [],
|
||||
@ -230,7 +231,8 @@ class Settings(QtCore.QSettings):
|
||||
'shortcuts/playSlidesLoop': [],
|
||||
'shortcuts/playSlidesOnce': [],
|
||||
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
|
||||
'shortcuts/previousItem_preview': [],
|
||||
'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||
'shortcuts/printServiceItem': [QtGui.QKeySequence('Ctrl+P')],
|
||||
'shortcuts/songExportItem': [],
|
||||
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
|
||||
|
@ -115,6 +115,7 @@ class UiStrings(object):
|
||||
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
|
||||
self.PlaySlidesToEnd = translate('OpenLP.Ui', 'Play Slides to End')
|
||||
self.Preview = translate('OpenLP.Ui', 'Preview')
|
||||
self.PreviewToolbar = translate('OpenLP.Ui', 'Preview Toolbar')
|
||||
self.PrintService = translate('OpenLP.Ui', 'Print Service')
|
||||
self.Projector = translate('OpenLP.Ui', 'Projector', 'Singular')
|
||||
self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')
|
||||
|
@ -408,7 +408,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
self.set_live_hot_keys(self)
|
||||
self.__add_actions_to_widget(self.controller)
|
||||
else:
|
||||
self.preview_widget.doubleClicked.connect(self.on_preview_add_to_service)
|
||||
self.preview_widget.doubleClicked.connect(self.on_preview_double_click)
|
||||
self.toolbar.set_widget_visible(['editSong'], False)
|
||||
self.controller.addActions([self.next_item, self.previous_item])
|
||||
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
|
||||
@ -1309,18 +1309,21 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
if self.service_item:
|
||||
self.service_manager.add_service_item(self.service_item)
|
||||
|
||||
def on_go_live_click(self, field=None):
|
||||
def on_preview_double_click(self, field=None):
|
||||
"""
|
||||
triggered by clicking the Preview slide items
|
||||
Triggered when a preview slide item is doubleclicked
|
||||
"""
|
||||
if Settings().value('advanced/double click live'):
|
||||
# Live and Preview have issues if we have video or presentations
|
||||
# playing in both at the same time.
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
if self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
self.on_go_live()
|
||||
if self.service_item:
|
||||
if Settings().value('advanced/double click live'):
|
||||
# Live and Preview have issues if we have video or presentations
|
||||
# playing in both at the same time.
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
if self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
self.on_go_live()
|
||||
else:
|
||||
self.on_preview_add_to_service()
|
||||
|
||||
def on_go_live(self, field=None):
|
||||
"""
|
||||
@ -1418,7 +1421,7 @@ class PreviewController(RegistryMixin, OpenLPMixin, SlideController):
|
||||
super(PreviewController, self).__init__(parent)
|
||||
self.split = 0
|
||||
self.type_prefix = 'preview'
|
||||
self.category = None
|
||||
self.category = 'Preview Toolbar'
|
||||
|
||||
def bootstrap_post_set_up(self):
|
||||
"""
|
||||
|
@ -73,7 +73,7 @@ class CSVBible(BibleDB):
|
||||
"""
|
||||
log.info(self.__class__.__name__)
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
self.books_file = kwargs['books_file']
|
||||
self.books_file = kwargs['booksfile']
|
||||
self.verses_file = kwargs['versefile']
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
@ -93,23 +93,20 @@ class CSVBible(BibleDB):
|
||||
# Populate the Tables
|
||||
try:
|
||||
details = get_file_encoding(self.books_file)
|
||||
books_file = open(self.books_file, 'r')
|
||||
if not books_file.read(3) == '\xEF\xBB\xBF':
|
||||
# no BOM was found
|
||||
books_file.seek(0)
|
||||
books_file = open(self.books_file, 'r', encoding=details['encoding'])
|
||||
books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
|
||||
for line in books_reader:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing books... %s') %
|
||||
str(line[2], details['encoding']))
|
||||
book_ref_id = self.get_book_ref_id_by_name(str(line[2], details['encoding']), 67, language_id)
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing books... %s')
|
||||
% line[2])
|
||||
book_ref_id = self.get_book_ref_id_by_name(line[2], 67, language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "%s" failed' % self.books_file)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
self.create_book(str(line[2], details['encoding']), book_ref_id, book_details['testament_id'])
|
||||
book_list[int(line[0])] = str(line[2], details['encoding'])
|
||||
self.create_book(line[2], book_ref_id, book_details['testament_id'])
|
||||
book_list.update({int(line[0]): line[2]})
|
||||
self.application.process_events()
|
||||
except (IOError, IndexError):
|
||||
log.exception('Loading books from file failed')
|
||||
@ -125,10 +122,7 @@ class CSVBible(BibleDB):
|
||||
try:
|
||||
book_ptr = None
|
||||
details = get_file_encoding(self.verses_file)
|
||||
verse_file = open(self.verses_file, 'rb')
|
||||
if not verse_file.read(3) == '\xEF\xBB\xBF':
|
||||
# no BOM was found
|
||||
verse_file.seek(0)
|
||||
verse_file = open(self.verses_file, 'r', encoding=details['encoding'])
|
||||
verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
|
||||
for line in verse_reader:
|
||||
if self.stop_import_flag:
|
||||
@ -136,7 +130,7 @@ class CSVBible(BibleDB):
|
||||
try:
|
||||
line_book = book_list[int(line[0])]
|
||||
except ValueError:
|
||||
line_book = str(line[0], details['encoding'])
|
||||
line_book = line[0]
|
||||
if book_ptr != line_book:
|
||||
book = self.get_book(line_book)
|
||||
book_ptr = book.name
|
||||
@ -144,10 +138,7 @@ class CSVBible(BibleDB):
|
||||
translate('BiblesPlugin.CSVBible',
|
||||
'Importing verses from %s...' % book.name, 'Importing verses from <book name>...'))
|
||||
self.session.commit()
|
||||
try:
|
||||
verse_text = str(line[3], details['encoding'])
|
||||
except UnicodeError:
|
||||
verse_text = str(line[3], 'cp1252')
|
||||
verse_text = line[3]
|
||||
self.create_verse(book.id, line[1], line[2], verse_text)
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.'))
|
||||
self.application.process_events()
|
||||
@ -170,7 +161,7 @@ def get_file_encoding(filename):
|
||||
"""
|
||||
detect_file = None
|
||||
try:
|
||||
detect_file = open(filename, 'r')
|
||||
detect_file = open(filename, 'rb')
|
||||
details = chardet.detect(detect_file.read(1024))
|
||||
except IOError:
|
||||
log.exception('Error detecting file encoding')
|
||||
|
@ -82,9 +82,11 @@ class VerseReferenceList(object):
|
||||
if result[-1] not in [';', ',', '.']:
|
||||
result += ';'
|
||||
result += ' '
|
||||
result = '%s%s, %s' % (result, version['version'], version['copyright'])
|
||||
result += version['version']
|
||||
if version['copyright'].strip():
|
||||
result += ', ' + version['copyright']
|
||||
if version['permission'].strip():
|
||||
result = result + ', ' + version['permission']
|
||||
result += ', ' + version['permission']
|
||||
result = result.rstrip()
|
||||
if result.endswith(','):
|
||||
return result[:len(result) - 1]
|
||||
|
97
tests/functional/openlp_plugins/bibles/test_csvimport.py
Normal file
97
tests/functional/openlp_plugins/bibles/test_csvimport.py
Normal file
@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2015 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
This module contains tests for the CSV Bible importer.
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from unittest import TestCase
|
||||
|
||||
from tests.functional import MagicMock, patch
|
||||
from openlp.plugins.bibles.lib.csvbible import CSVBible
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
|
||||
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', '..', 'resources', 'bibles'))
|
||||
|
||||
|
||||
class TestCSVImport(TestCase):
|
||||
"""
|
||||
Test the functions in the :mod:`csvimport` module.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.registry_patcher = patch('openlp.plugins.bibles.lib.db.Registry')
|
||||
self.registry_patcher.start()
|
||||
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
|
||||
self.manager_patcher.start()
|
||||
|
||||
def tearDown(self):
|
||||
self.registry_patcher.stop()
|
||||
self.manager_patcher.stop()
|
||||
|
||||
def create_importer_test(self):
|
||||
"""
|
||||
Test creating an instance of the CSV file importer
|
||||
"""
|
||||
# GIVEN: A mocked out "manager"
|
||||
mocked_manager = MagicMock()
|
||||
|
||||
# WHEN: An importer object is created
|
||||
importer = CSVBible(mocked_manager, path='.', name='.', booksfile='.', versefile='.')
|
||||
|
||||
# THEN: The importer should be an instance of BibleDB
|
||||
self.assertIsInstance(importer, BibleDB)
|
||||
|
||||
def file_import_test(self):
|
||||
"""
|
||||
Test the actual import of CSV Bible file
|
||||
"""
|
||||
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
|
||||
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
|
||||
result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb')
|
||||
test_data = json.loads(result_file.read().decode())
|
||||
books_file = os.path.join(TEST_PATH, 'dk1933-books.csv')
|
||||
verses_file = os.path.join(TEST_PATH, 'dk1933-verses.csv')
|
||||
with patch('openlp.plugins.bibles.lib.csvbible.CSVBible.application'):
|
||||
mocked_manager = MagicMock()
|
||||
mocked_import_wizard = MagicMock()
|
||||
importer = CSVBible(mocked_manager, path='.', name='.', booksfile=books_file, versefile=verses_file)
|
||||
importer.wizard = mocked_import_wizard
|
||||
importer.get_book_ref_id_by_name = MagicMock()
|
||||
importer.create_verse = MagicMock()
|
||||
importer.create_book = MagicMock()
|
||||
importer.session = MagicMock()
|
||||
importer.get_language = MagicMock()
|
||||
importer.get_language.return_value = 'Danish'
|
||||
importer.get_book = MagicMock()
|
||||
|
||||
# WHEN: Importing bible file
|
||||
importer.do_import()
|
||||
|
||||
# THEN: The create_verse() method should have been called with each verse in the file.
|
||||
self.assertTrue(importer.create_verse.called)
|
||||
for verse_tag, verse_text in test_data['verses']:
|
||||
importer.create_verse.assert_any_call(importer.get_book().id, '1', verse_tag, verse_text)
|
||||
importer.create_book.assert_any_call('1. Mosebog', importer.get_book_ref_id_by_name(), 1)
|
||||
importer.create_book.assert_any_call('1. Krønikebog', importer.get_book_ref_id_by_name(), 1)
|
22
tests/resources/bibles/dk1933-books.csv
Normal file
22
tests/resources/bibles/dk1933-books.csv
Normal file
@ -0,0 +1,22 @@
|
||||
1,1,1. Mosebog,1Mos
|
||||
2,1,2. Mosebog,2Mos
|
||||
3,1,3. Mosebog,3Mos
|
||||
4,1,4. Mosebog,4Mos
|
||||
5,1,5. Mosebog,5Mos
|
||||
6,1,Josvabogen,jos
|
||||
7,1,Dommerbogen,dom
|
||||
8,1,Ruths Bog,ruth
|
||||
9,1,1. Samuelsbog,1Sam
|
||||
10,1,2. Samuelsbog,2Sam
|
||||
11,1,1. Kongebog,1kong
|
||||
12,1,2. Kongebog,2kong
|
||||
13,1,1. Krønikebog,1kron
|
||||
14,1,2. Krønikebog,2kron
|
||||
15,1,Ezras Bog,ezra
|
||||
16,1,Nehemias' Bog,neh
|
||||
17,1,Esters Bog,est
|
||||
18,1,Jobs Bog,job
|
||||
19,1,Salmernes Bog,sl
|
||||
20,1,Ordsprogenes Bog,ordsp
|
||||
21,1,Prædikerens Bog,prad
|
||||
22,1,Højsangen,hojs
|
|
10
tests/resources/bibles/dk1933-verses.csv
Normal file
10
tests/resources/bibles/dk1933-verses.csv
Normal file
@ -0,0 +1,10 @@
|
||||
1,1,1,"I Begyndelsen skabte Gud Himmelen og Jorden."
|
||||
1,1,2,"Og Jorden var øde og tom, og der var Mørke over Verdensdybet. Men Guds Ånd svævede over Vandene."
|
||||
1,1,3,"Og Gud sagde: ""Der blive Lys!"" Og der blev Lys."
|
||||
1,1,4,"Og Gud så, at Lyset var godt, og Gud satte Skel mellem Lyset og Mørket,"
|
||||
1,1,5,"og Gud kaldte Lyset Dag, og Mørket kaldte han Nat. Og det blev Aften, og det blev Morgen, første Dag."
|
||||
1,1,6,"Derpå sagde Gud: ""Der blive en Hvælving midt i Vandene til at skille Vandene ad!"""
|
||||
1,1,7,"Og således skete det: Gud gjorde Hvælvingen og skilte Vandet under Hvælvingen fra Vandet over Hvælvingen;"
|
||||
1,1,8,"og Gud kaldte Hvælvingen Himmel. Og det blev Aften, og det blev Morgen, anden Dag."
|
||||
1,1,9,"Derpå sagde Gud: ""Vandet under Himmelen samle sig på eet Sted, så det faste Land kommer til Syne!"" Og således skete det;"
|
||||
1,1,10,"og Gud kaldte det faste Land Jord, og Stedet, hvor Vandet samlede sig, kaldte han Hav. Og Gud så, at det var godt."
|
|
Loading…
Reference in New Issue
Block a user