forked from openlp/openlp
Head
This commit is contained in:
commit
cade36a332
201
openlp/core/common/languages.py
Normal file
201
openlp/core/common/languages.py
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2016 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 #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`languages` module provides a list of language names with utility functions.
|
||||||
|
"""
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from openlp.core.common import translate
|
||||||
|
|
||||||
|
|
||||||
|
Language = namedtuple('Language', ['id', 'name', 'code'])
|
||||||
|
languages = sorted([
|
||||||
|
Language(1, translate('common.languages', '(Afan) Oromo', 'Language code: om'), 'om'),
|
||||||
|
Language(2, translate('common.languages', 'Abkhazian', 'Language code: ab'), 'ab'),
|
||||||
|
Language(3, translate('common.languages', 'Afar', 'Language code: aa'), 'aa'),
|
||||||
|
Language(4, translate('common.languages', 'Afrikaans', 'Language code: af'), 'af'),
|
||||||
|
Language(5, translate('common.languages', 'Albanian', 'Language code: sq'), 'sq'),
|
||||||
|
Language(6, translate('common.languages', 'Amharic', 'Language code: am'), 'am'),
|
||||||
|
Language(140, translate('common.languages', 'Amuzgo', 'Language code: amu'), 'amu'),
|
||||||
|
Language(152, translate('common.languages', 'Ancient Greek', 'Language code: grc'), 'grc'),
|
||||||
|
Language(7, translate('common.languages', 'Arabic', 'Language code: ar'), 'ar'),
|
||||||
|
Language(8, translate('common.languages', 'Armenian', 'Language code: hy'), 'hy'),
|
||||||
|
Language(9, translate('common.languages', 'Assamese', 'Language code: as'), 'as'),
|
||||||
|
Language(10, translate('common.languages', 'Aymara', 'Language code: ay'), 'ay'),
|
||||||
|
Language(11, translate('common.languages', 'Azerbaijani', 'Language code: az'), 'az'),
|
||||||
|
Language(12, translate('common.languages', 'Bashkir', 'Language code: ba'), 'ba'),
|
||||||
|
Language(13, translate('common.languages', 'Basque', 'Language code: eu'), 'eu'),
|
||||||
|
Language(14, translate('common.languages', 'Bengali', 'Language code: bn'), 'bn'),
|
||||||
|
Language(15, translate('common.languages', 'Bhutani', 'Language code: dz'), 'dz'),
|
||||||
|
Language(16, translate('common.languages', 'Bihari', 'Language code: bh'), 'bh'),
|
||||||
|
Language(17, translate('common.languages', 'Bislama', 'Language code: bi'), 'bi'),
|
||||||
|
Language(18, translate('common.languages', 'Breton', 'Language code: br'), 'br'),
|
||||||
|
Language(19, translate('common.languages', 'Bulgarian', 'Language code: bg'), 'bg'),
|
||||||
|
Language(20, translate('common.languages', 'Burmese', 'Language code: my'), 'my'),
|
||||||
|
Language(21, translate('common.languages', 'Byelorussian', 'Language code: be'), 'be'),
|
||||||
|
Language(142, translate('common.languages', 'Cakchiquel', 'Language code: cak'), 'cak'),
|
||||||
|
Language(22, translate('common.languages', 'Cambodian', 'Language code: km'), 'km'),
|
||||||
|
Language(23, translate('common.languages', 'Catalan', 'Language code: ca'), 'ca'),
|
||||||
|
Language(24, translate('common.languages', 'Chinese', 'Language code: zh'), 'zh'),
|
||||||
|
Language(141, translate('common.languages', 'Comaltepec Chinantec', 'Language code: cco'), 'cco'),
|
||||||
|
Language(25, translate('common.languages', 'Corsican', 'Language code: co'), 'co'),
|
||||||
|
Language(26, translate('common.languages', 'Croatian', 'Language code: hr'), 'hr'),
|
||||||
|
Language(27, translate('common.languages', 'Czech', 'Language code: cs'), 'cs'),
|
||||||
|
Language(28, translate('common.languages', 'Danish', 'Language code: da'), 'da'),
|
||||||
|
Language(29, translate('common.languages', 'Dutch', 'Language code: nl'), 'nl'),
|
||||||
|
Language(30, translate('common.languages', 'English', 'Language code: en'), 'en'),
|
||||||
|
Language(31, translate('common.languages', 'Esperanto', 'Language code: eo'), 'eo'),
|
||||||
|
Language(32, translate('common.languages', 'Estonian', 'Language code: et'), 'et'),
|
||||||
|
Language(33, translate('common.languages', 'Faeroese', 'Language code: fo'), 'fo'),
|
||||||
|
Language(34, translate('common.languages', 'Fiji', 'Language code: fj'), 'fj'),
|
||||||
|
Language(35, translate('common.languages', 'Finnish', 'Language code: fi'), 'fi'),
|
||||||
|
Language(36, translate('common.languages', 'French', 'Language code: fr'), 'fr'),
|
||||||
|
Language(37, translate('common.languages', 'Frisian', 'Language code: fy'), 'fy'),
|
||||||
|
Language(38, translate('common.languages', 'Galician', 'Language code: gl'), 'gl'),
|
||||||
|
Language(39, translate('common.languages', 'Georgian', 'Language code: ka'), 'ka'),
|
||||||
|
Language(40, translate('common.languages', 'German', 'Language code: de'), 'de'),
|
||||||
|
Language(41, translate('common.languages', 'Greek', 'Language code: el'), 'el'),
|
||||||
|
Language(42, translate('common.languages', 'Greenlandic', 'Language code: kl'), 'kl'),
|
||||||
|
Language(43, translate('common.languages', 'Guarani', 'Language code: gn'), 'gn'),
|
||||||
|
Language(44, translate('common.languages', 'Gujarati', 'Language code: gu'), 'gu'),
|
||||||
|
Language(143, translate('common.languages', 'Haitian Creole', 'Language code: ht'), 'ht'),
|
||||||
|
Language(45, translate('common.languages', 'Hausa', 'Language code: ha'), 'ha'),
|
||||||
|
Language(46, translate('common.languages', 'Hebrew (former iw)', 'Language code: he'), 'he'),
|
||||||
|
Language(144, translate('common.languages', 'Hiligaynon', 'Language code: hil'), 'hil'),
|
||||||
|
Language(47, translate('common.languages', 'Hindi', 'Language code: hi'), 'hi'),
|
||||||
|
Language(48, translate('common.languages', 'Hungarian', 'Language code: hu'), 'hu'),
|
||||||
|
Language(49, translate('common.languages', 'Icelandic', 'Language code: is'), 'is'),
|
||||||
|
Language(50, translate('common.languages', 'Indonesian (former in)', 'Language code: id'), 'id'),
|
||||||
|
Language(51, translate('common.languages', 'Interlingua', 'Language code: ia'), 'ia'),
|
||||||
|
Language(52, translate('common.languages', 'Interlingue', 'Language code: ie'), 'ie'),
|
||||||
|
Language(54, translate('common.languages', 'Inuktitut (Eskimo)', 'Language code: iu'), 'iu'),
|
||||||
|
Language(53, translate('common.languages', 'Inupiak', 'Language code: ik'), 'ik'),
|
||||||
|
Language(55, translate('common.languages', 'Irish', 'Language code: ga'), 'ga'),
|
||||||
|
Language(56, translate('common.languages', 'Italian', 'Language code: it'), 'it'),
|
||||||
|
Language(145, translate('common.languages', 'Jakalteko', 'Language code: jac'), 'jac'),
|
||||||
|
Language(57, translate('common.languages', 'Japanese', 'Language code: ja'), 'ja'),
|
||||||
|
Language(58, translate('common.languages', 'Javanese', 'Language code: jw'), 'jw'),
|
||||||
|
Language(150, translate('common.languages', 'K\'iche\'', 'Language code: quc'), 'quc'),
|
||||||
|
Language(59, translate('common.languages', 'Kannada', 'Language code: kn'), 'kn'),
|
||||||
|
Language(60, translate('common.languages', 'Kashmiri', 'Language code: ks'), 'ks'),
|
||||||
|
Language(61, translate('common.languages', 'Kazakh', 'Language code: kk'), 'kk'),
|
||||||
|
Language(146, translate('common.languages', 'Kekchí ', 'Language code: kek'), 'kek'),
|
||||||
|
Language(62, translate('common.languages', 'Kinyarwanda', 'Language code: rw'), 'rw'),
|
||||||
|
Language(63, translate('common.languages', 'Kirghiz', 'Language code: ky'), 'ky'),
|
||||||
|
Language(64, translate('common.languages', 'Kirundi', 'Language code: rn'), 'rn'),
|
||||||
|
Language(65, translate('common.languages', 'Korean', 'Language code: ko'), 'ko'),
|
||||||
|
Language(66, translate('common.languages', 'Kurdish', 'Language code: ku'), 'ku'),
|
||||||
|
Language(67, translate('common.languages', 'Laothian', 'Language code: lo'), 'lo'),
|
||||||
|
Language(68, translate('common.languages', 'Latin', 'Language code: la'), 'la'),
|
||||||
|
Language(69, translate('common.languages', 'Latvian, Lettish', 'Language code: lv'), 'lv'),
|
||||||
|
Language(70, translate('common.languages', 'Lingala', 'Language code: ln'), 'ln'),
|
||||||
|
Language(71, translate('common.languages', 'Lithuanian', 'Language code: lt'), 'lt'),
|
||||||
|
Language(72, translate('common.languages', 'Macedonian', 'Language code: mk'), 'mk'),
|
||||||
|
Language(73, translate('common.languages', 'Malagasy', 'Language code: mg'), 'mg'),
|
||||||
|
Language(74, translate('common.languages', 'Malay', 'Language code: ms'), 'ms'),
|
||||||
|
Language(75, translate('common.languages', 'Malayalam', 'Language code: ml'), 'ml'),
|
||||||
|
Language(76, translate('common.languages', 'Maltese', 'Language code: mt'), 'mt'),
|
||||||
|
Language(148, translate('common.languages', 'Mam', 'Language code: mam'), 'mam'),
|
||||||
|
Language(77, translate('common.languages', 'Maori', 'Language code: mi'), 'mi'),
|
||||||
|
Language(147, translate('common.languages', 'Maori', 'Language code: mri'), 'mri'),
|
||||||
|
Language(78, translate('common.languages', 'Marathi', 'Language code: mr'), 'mr'),
|
||||||
|
Language(79, translate('common.languages', 'Moldavian', 'Language code: mo'), 'mo'),
|
||||||
|
Language(80, translate('common.languages', 'Mongolian', 'Language code: mn'), 'mn'),
|
||||||
|
Language(149, translate('common.languages', 'Nahuatl', 'Language code: nah'), 'nah'),
|
||||||
|
Language(81, translate('common.languages', 'Nauru', 'Language code: na'), 'na'),
|
||||||
|
Language(82, translate('common.languages', 'Nepali', 'Language code: ne'), 'ne'),
|
||||||
|
Language(83, translate('common.languages', 'Norwegian', 'Language code: no'), 'no'),
|
||||||
|
Language(84, translate('common.languages', 'Occitan', 'Language code: oc'), 'oc'),
|
||||||
|
Language(85, translate('common.languages', 'Oriya', 'Language code: or'), 'or'),
|
||||||
|
Language(86, translate('common.languages', 'Pashto, Pushto', 'Language code: ps'), 'ps'),
|
||||||
|
Language(87, translate('common.languages', 'Persian', 'Language code: fa'), 'fa'),
|
||||||
|
Language(151, translate('common.languages', 'Plautdietsch', 'Language code: pdt'), 'pdt'),
|
||||||
|
Language(88, translate('common.languages', 'Polish', 'Language code: pl'), 'pl'),
|
||||||
|
Language(89, translate('common.languages', 'Portuguese', 'Language code: pt'), 'pt'),
|
||||||
|
Language(90, translate('common.languages', 'Punjabi', 'Language code: pa'), 'pa'),
|
||||||
|
Language(91, translate('common.languages', 'Quechua', 'Language code: qu'), 'qu'),
|
||||||
|
Language(92, translate('common.languages', 'Rhaeto-Romance', 'Language code: rm'), 'rm'),
|
||||||
|
Language(93, translate('common.languages', 'Romanian', 'Language code: ro'), 'ro'),
|
||||||
|
Language(94, translate('common.languages', 'Russian', 'Language code: ru'), 'ru'),
|
||||||
|
Language(95, translate('common.languages', 'Samoan', 'Language code: sm'), 'sm'),
|
||||||
|
Language(96, translate('common.languages', 'Sangro', 'Language code: sg'), 'sg'),
|
||||||
|
Language(97, translate('common.languages', 'Sanskrit', 'Language code: sa'), 'sa'),
|
||||||
|
Language(98, translate('common.languages', 'Scots Gaelic', 'Language code: gd'), 'gd'),
|
||||||
|
Language(99, translate('common.languages', 'Serbian', 'Language code: sr'), 'sr'),
|
||||||
|
Language(100, translate('common.languages', 'Serbo-Croatian', 'Language code: sh'), 'sh'),
|
||||||
|
Language(101, translate('common.languages', 'Sesotho', 'Language code: st'), 'st'),
|
||||||
|
Language(102, translate('common.languages', 'Setswana', 'Language code: tn'), 'tn'),
|
||||||
|
Language(103, translate('common.languages', 'Shona', 'Language code: sn'), 'sn'),
|
||||||
|
Language(104, translate('common.languages', 'Sindhi', 'Language code: sd'), 'sd'),
|
||||||
|
Language(105, translate('common.languages', 'Singhalese', 'Language code: si'), 'si'),
|
||||||
|
Language(106, translate('common.languages', 'Siswati', 'Language code: ss'), 'ss'),
|
||||||
|
Language(107, translate('common.languages', 'Slovak', 'Language code: sk'), 'sk'),
|
||||||
|
Language(108, translate('common.languages', 'Slovenian', 'Language code: sl'), 'sl'),
|
||||||
|
Language(109, translate('common.languages', 'Somali', 'Language code: so'), 'so'),
|
||||||
|
Language(110, translate('common.languages', 'Spanish', 'Language code: es'), 'es'),
|
||||||
|
Language(111, translate('common.languages', 'Sudanese', 'Language code: su'), 'su'),
|
||||||
|
Language(112, translate('common.languages', 'Swahili', 'Language code: sw'), 'sw'),
|
||||||
|
Language(113, translate('common.languages', 'Swedish', 'Language code: sv'), 'sv'),
|
||||||
|
Language(114, translate('common.languages', 'Tagalog', 'Language code: tl'), 'tl'),
|
||||||
|
Language(115, translate('common.languages', 'Tajik', 'Language code: tg'), 'tg'),
|
||||||
|
Language(116, translate('common.languages', 'Tamil', 'Language code: ta'), 'ta'),
|
||||||
|
Language(117, translate('common.languages', 'Tatar', 'Language code: tt'), 'tt'),
|
||||||
|
Language(118, translate('common.languages', 'Tegulu', 'Language code: te'), 'te'),
|
||||||
|
Language(119, translate('common.languages', 'Thai', 'Language code: th'), 'th'),
|
||||||
|
Language(120, translate('common.languages', 'Tibetan', 'Language code: bo'), 'bo'),
|
||||||
|
Language(121, translate('common.languages', 'Tigrinya', 'Language code: ti'), 'ti'),
|
||||||
|
Language(122, translate('common.languages', 'Tonga', 'Language code: to'), 'to'),
|
||||||
|
Language(123, translate('common.languages', 'Tsonga', 'Language code: ts'), 'ts'),
|
||||||
|
Language(124, translate('common.languages', 'Turkish', 'Language code: tr'), 'tr'),
|
||||||
|
Language(125, translate('common.languages', 'Turkmen', 'Language code: tk'), 'tk'),
|
||||||
|
Language(126, translate('common.languages', 'Twi', 'Language code: tw'), 'tw'),
|
||||||
|
Language(127, translate('common.languages', 'Uigur', 'Language code: ug'), 'ug'),
|
||||||
|
Language(128, translate('common.languages', 'Ukrainian', 'Language code: uk'), 'uk'),
|
||||||
|
Language(129, translate('common.languages', 'Urdu', 'Language code: ur'), 'ur'),
|
||||||
|
Language(153, translate('common.languages', 'Uspanteco', 'Language code: usp'), 'usp'),
|
||||||
|
Language(130, translate('common.languages', 'Uzbek', 'Language code: uz'), 'uz'),
|
||||||
|
Language(131, translate('common.languages', 'Vietnamese', 'Language code: vi'), 'vi'),
|
||||||
|
Language(132, translate('common.languages', 'Volapuk', 'Language code: vo'), 'vo'),
|
||||||
|
Language(133, translate('common.languages', 'Welch', 'Language code: cy'), 'cy'),
|
||||||
|
Language(134, translate('common.languages', 'Wolof', 'Language code: wo'), 'wo'),
|
||||||
|
Language(135, translate('common.languages', 'Xhosa', 'Language code: xh'), 'xh'),
|
||||||
|
Language(136, translate('common.languages', 'Yiddish (former ji)', 'Language code: yi'), 'yi'),
|
||||||
|
Language(137, translate('common.languages', 'Yoruba', 'Language code: yo'), 'yo'),
|
||||||
|
Language(138, translate('common.languages', 'Zhuang', 'Language code: za'), 'za'),
|
||||||
|
Language(139, translate('common.languages', 'Zulu', 'Language code: zu'), 'zu')
|
||||||
|
], key=lambda language: language.name)
|
||||||
|
|
||||||
|
|
||||||
|
def get_language(name):
|
||||||
|
"""
|
||||||
|
Find the language by its name or code.
|
||||||
|
|
||||||
|
:param name: The name or abbreviation of the language.
|
||||||
|
:return: The first match as a Language namedtuple or None
|
||||||
|
"""
|
||||||
|
if name:
|
||||||
|
name_lower = name.lower()
|
||||||
|
name_title = name_lower[:1].upper() + name_lower[1:]
|
||||||
|
for language in languages:
|
||||||
|
if language.name == name_title or language.code == name_lower:
|
||||||
|
return language
|
||||||
|
return None
|
@ -23,6 +23,7 @@
|
|||||||
The :mod:`uistrings` module provides standard strings for OpenLP.
|
The :mod:`uistrings` module provides standard strings for OpenLP.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
import itertools
|
||||||
|
|
||||||
from openlp.core.common import translate
|
from openlp.core.common import translate
|
||||||
|
|
||||||
@ -153,3 +154,30 @@ class UiStrings(object):
|
|||||||
self.View = translate('OpenLP.Ui', 'View')
|
self.View = translate('OpenLP.Ui', 'View')
|
||||||
self.ViewMode = translate('OpenLP.Ui', 'View Mode')
|
self.ViewMode = translate('OpenLP.Ui', 'View Mode')
|
||||||
self.Video = translate('OpenLP.Ui', 'Video')
|
self.Video = translate('OpenLP.Ui', 'Video')
|
||||||
|
self.BibleShortSearchTitle = translate('OpenLP.Ui', 'Search is Empty or too Short')
|
||||||
|
self.BibleShortSearch = translate('OpenLP.Ui', '<strong>The search you have entered is empty or shorter '
|
||||||
|
'than 3 characters long.</strong><br><br>Please try again with '
|
||||||
|
'a longer search.')
|
||||||
|
self.BibleNoBiblesTitle = translate('OpenLP.Ui', 'No Bibles Available')
|
||||||
|
self.BibleNoBibles = translate('OpenLP.Ui', '<strong>There are no Bibles currently installed.</strong><br><br>'
|
||||||
|
'Please use the Import Wizard to install one or more Bibles.')
|
||||||
|
book_chapter = translate('OpenLP.Ui', 'Book Chapter')
|
||||||
|
chapter = translate('OpenLP.Ui', 'Chapter')
|
||||||
|
verse = translate('OpenLP.Ui', 'Verse')
|
||||||
|
gap = ' | '
|
||||||
|
psalm = translate('OpenLP.Ui', 'Psalm')
|
||||||
|
may_shorten = translate('OpenLP.Ui', 'Book names may be shortened from full names, for an example Ps 23 = '
|
||||||
|
'Psalm 23')
|
||||||
|
bible_scripture_items = \
|
||||||
|
[book_chapter, gap, psalm, ' 23<br>',
|
||||||
|
book_chapter, '%(range)s', chapter, gap, psalm, ' 23%(range)s24<br>',
|
||||||
|
book_chapter, '%(verse)s', verse, '%(range)s', verse, gap, psalm, ' 23%(verse)s1%(range)s2<br>',
|
||||||
|
book_chapter, '%(verse)s', verse, '%(range)s', verse, '%(list)s', verse, '%(range)s', verse, gap, psalm,
|
||||||
|
' 23%(verse)s1%(range)s2%(list)s5%(range)s6<br>',
|
||||||
|
book_chapter, '%(verse)s', verse, '%(range)s', verse, '%(list)s', chapter, '%(verse)s', verse, '%(range)s',
|
||||||
|
verse, gap, psalm, ' 23%(verse)s1%(range)s2%(list)s24%(verse)s1%(range)s3<br>',
|
||||||
|
book_chapter, '%(verse)s', verse, '%(range)s', chapter, '%(verse)s', verse, gap, psalm,
|
||||||
|
' 23%(verse)s1%(range)s24%(verse)s1<br><br>', may_shorten]
|
||||||
|
itertools.chain.from_iterable(itertools.repeat(strings, 1) if isinstance(strings, str)
|
||||||
|
else strings for strings in bible_scripture_items)
|
||||||
|
self.BibleScriptureError = ''.join(str(joined) for joined in bible_scripture_items)
|
||||||
|
@ -651,6 +651,20 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||||||
item.setFont(font)
|
item.setFont(font)
|
||||||
self.list_view.addItem(item)
|
self.list_view.addItem(item)
|
||||||
|
|
||||||
|
def check_search_result_search_while_typing_short(self):
|
||||||
|
"""
|
||||||
|
This is used in Bible "Search while typing" if the search is shorter than the min required len.
|
||||||
|
"""
|
||||||
|
if self.list_view.count():
|
||||||
|
return
|
||||||
|
message = translate('OpenLP.MediaManagerItem', 'Search is too short to be used in: "Search while typing"')
|
||||||
|
item = QtWidgets.QListWidgetItem(message)
|
||||||
|
item.setFlags(QtCore.Qt.NoItemFlags)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setItalic(True)
|
||||||
|
item.setFont(font)
|
||||||
|
self.list_view.addItem(item)
|
||||||
|
|
||||||
def _get_id_of_item_to_generate(self, item, remote_item):
|
def _get_id_of_item_to_generate(self, item, remote_item):
|
||||||
"""
|
"""
|
||||||
Utility method to check items being submitted for slide generation.
|
Utility method to check items being submitted for slide generation.
|
||||||
|
@ -474,6 +474,7 @@ class ThemeXML(object):
|
|||||||
if element.startswith('shadow') or element.startswith('outline'):
|
if element.startswith('shadow') or element.startswith('outline'):
|
||||||
master = 'font_main'
|
master = 'font_main'
|
||||||
# fix bold font
|
# fix bold font
|
||||||
|
ret_value = None
|
||||||
if element == 'weight':
|
if element == 'weight':
|
||||||
element = 'bold'
|
element = 'bold'
|
||||||
if value == 'Normal':
|
if value == 'Normal':
|
||||||
@ -482,7 +483,7 @@ class ThemeXML(object):
|
|||||||
ret_value = True
|
ret_value = True
|
||||||
if element == 'proportion':
|
if element == 'proportion':
|
||||||
element = 'size'
|
element = 'size'
|
||||||
return False, master, element, ret_value
|
return False, master, element, ret_value if ret_value is not None else value
|
||||||
|
|
||||||
def _create_attr(self, master, element, value):
|
def _create_attr(self, master, element, value):
|
||||||
"""
|
"""
|
||||||
|
@ -41,7 +41,8 @@ __default_settings__ = {
|
|||||||
'bibles/db password': '',
|
'bibles/db password': '',
|
||||||
'bibles/db hostname': '',
|
'bibles/db hostname': '',
|
||||||
'bibles/db database': '',
|
'bibles/db database': '',
|
||||||
'bibles/last search type': BibleSearch.Reference,
|
'bibles/last search type': BibleSearch.Combined,
|
||||||
|
'bibles/reset to combined quick search': True,
|
||||||
'bibles/verse layout style': LayoutStyle.VersePerSlide,
|
'bibles/verse layout style': LayoutStyle.VersePerSlide,
|
||||||
'bibles/book name language': LanguageSelection.Bible,
|
'bibles/book name language': LanguageSelection.Bible,
|
||||||
'bibles/display brackets': DisplayStyle.NoBrackets,
|
'bibles/display brackets': DisplayStyle.NoBrackets,
|
||||||
@ -59,7 +60,9 @@ __default_settings__ = {
|
|||||||
'bibles/range separator': '',
|
'bibles/range separator': '',
|
||||||
'bibles/list separator': '',
|
'bibles/list separator': '',
|
||||||
'bibles/end separator': '',
|
'bibles/end separator': '',
|
||||||
'bibles/last directory import': ''
|
'bibles/last directory import': '',
|
||||||
|
'bibles/hide combined quick error': False,
|
||||||
|
'bibles/is search while typing enabled': True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ from PyQt5.QtWidgets import QDialog
|
|||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
|
|
||||||
from openlp.core.common import translate
|
from openlp.core.common import translate
|
||||||
|
from openlp.core.common.languages import languages
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.plugins.bibles.forms.languagedialog import Ui_LanguageDialog
|
from openlp.plugins.bibles.forms.languagedialog import Ui_LanguageDialog
|
||||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -51,11 +51,11 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
def exec(self, bible_name):
|
def exec(self, bible_name):
|
||||||
self.language_combo_box.addItem('')
|
|
||||||
if bible_name:
|
if bible_name:
|
||||||
self.bible_label.setText(str(bible_name))
|
self.bible_label.setText(bible_name)
|
||||||
items = BiblesResourcesDB.get_languages()
|
self.language_combo_box.addItem('')
|
||||||
self.language_combo_box.addItems([item['name'] for item in items])
|
for language in languages:
|
||||||
|
self.language_combo_box.addItem(language.name, language.id)
|
||||||
return QDialog.exec(self)
|
return QDialog.exec(self)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
|
@ -128,6 +128,20 @@ class BiblesTab(SettingsTab):
|
|||||||
self.language_selection_layout.addWidget(self.language_selection_label)
|
self.language_selection_layout.addWidget(self.language_selection_label)
|
||||||
self.language_selection_layout.addWidget(self.language_selection_combo_box)
|
self.language_selection_layout.addWidget(self.language_selection_combo_box)
|
||||||
self.right_layout.addWidget(self.language_selection_group_box)
|
self.right_layout.addWidget(self.language_selection_group_box)
|
||||||
|
self.bible_quick_settings_group_box = QtWidgets.QGroupBox(self.right_column)
|
||||||
|
self.bible_quick_settings_group_box.setObjectName('bible_quick_settings_group_box')
|
||||||
|
self.right_layout.addWidget(self.bible_quick_settings_group_box)
|
||||||
|
self.search_settings_layout = QtWidgets.QFormLayout(self.bible_quick_settings_group_box)
|
||||||
|
self.search_settings_layout.setObjectName('search_settings_layout')
|
||||||
|
self.reset_to_combined_quick_search_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||||
|
self.reset_to_combined_quick_search_check_box.setObjectName('reset_to_combined_quick_search_check_box')
|
||||||
|
self.search_settings_layout.addRow(self.reset_to_combined_quick_search_check_box)
|
||||||
|
self.hide_combined_quick_error_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||||
|
self.hide_combined_quick_error_check_box.setObjectName('hide_combined_quick_error_check_box')
|
||||||
|
self.search_settings_layout.addRow(self.hide_combined_quick_error_check_box)
|
||||||
|
self.bible_search_while_typing_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||||
|
self.bible_search_while_typing_check_box.setObjectName('bible_search_while_typing_check_box')
|
||||||
|
self.search_settings_layout.addRow(self.bible_search_while_typing_check_box)
|
||||||
self.left_layout.addStretch()
|
self.left_layout.addStretch()
|
||||||
self.right_layout.addStretch()
|
self.right_layout.addStretch()
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
@ -151,6 +165,12 @@ class BiblesTab(SettingsTab):
|
|||||||
self.end_separator_line_edit.editingFinished.connect(self.on_end_separator_line_edit_finished)
|
self.end_separator_line_edit.editingFinished.connect(self.on_end_separator_line_edit_finished)
|
||||||
Registry().register_function('theme_update_list', self.update_theme_list)
|
Registry().register_function('theme_update_list', self.update_theme_list)
|
||||||
self.language_selection_combo_box.activated.connect(self.on_language_selection_combo_box_changed)
|
self.language_selection_combo_box.activated.connect(self.on_language_selection_combo_box_changed)
|
||||||
|
self.reset_to_combined_quick_search_check_box.stateChanged.connect(
|
||||||
|
self.on_reset_to_combined_quick_search_check_box_changed)
|
||||||
|
self.hide_combined_quick_error_check_box.stateChanged.connect(
|
||||||
|
self.on_hide_combined_quick_error_check_box_changed)
|
||||||
|
self.bible_search_while_typing_check_box.stateChanged.connect(
|
||||||
|
self.on_bible_search_while_typing_check_box_changed)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.verse_display_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Verse Display'))
|
self.verse_display_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Verse Display'))
|
||||||
@ -194,6 +214,17 @@ class BiblesTab(SettingsTab):
|
|||||||
LanguageSelection.Application, translate('BiblesPlugin.BiblesTab', 'Application Language'))
|
LanguageSelection.Application, translate('BiblesPlugin.BiblesTab', 'Application Language'))
|
||||||
self.language_selection_combo_box.setItemText(
|
self.language_selection_combo_box.setItemText(
|
||||||
LanguageSelection.English, translate('BiblesPlugin.BiblesTab', 'English'))
|
LanguageSelection.English, translate('BiblesPlugin.BiblesTab', 'English'))
|
||||||
|
self.bible_quick_settings_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Quick Search Settings'))
|
||||||
|
self.reset_to_combined_quick_search_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||||
|
'Reset search type to "Text or Scripture'
|
||||||
|
' Reference" on startup'))
|
||||||
|
self.hide_combined_quick_error_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||||
|
'Don\'t show error if nothing is found in "Text or '
|
||||||
|
'Scripture Reference"'))
|
||||||
|
self.bible_search_while_typing_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||||
|
'Search automatically while typing (Text search must'
|
||||||
|
' contain a\nminimum of {count} characters and a '
|
||||||
|
'space for performance reasons)').format(count='8'))
|
||||||
|
|
||||||
def on_bible_theme_combo_box_changed(self):
|
def on_bible_theme_combo_box_changed(self):
|
||||||
self.bible_theme = self.bible_theme_combo_box.currentText()
|
self.bible_theme = self.bible_theme_combo_box.currentText()
|
||||||
@ -302,6 +333,24 @@ class BiblesTab(SettingsTab):
|
|||||||
self.end_separator_line_edit.setText(get_reference_separator('sep_e_default'))
|
self.end_separator_line_edit.setText(get_reference_separator('sep_e_default'))
|
||||||
self.end_separator_line_edit.setPalette(self.get_grey_text_palette(True))
|
self.end_separator_line_edit.setPalette(self.get_grey_text_palette(True))
|
||||||
|
|
||||||
|
def on_reset_to_combined_quick_search_check_box_changed(self, check_state):
|
||||||
|
"""
|
||||||
|
Event handler for the 'hide_combined_quick_error' check box
|
||||||
|
"""
|
||||||
|
self.reset_to_combined_quick_search = (check_state == QtCore.Qt.Checked)
|
||||||
|
|
||||||
|
def on_hide_combined_quick_error_check_box_changed(self, check_state):
|
||||||
|
"""
|
||||||
|
Event handler for the 'hide_combined_quick_error' check box
|
||||||
|
"""
|
||||||
|
self.hide_combined_quick_error = (check_state == QtCore.Qt.Checked)
|
||||||
|
|
||||||
|
def on_bible_search_while_typing_check_box_changed(self, check_state):
|
||||||
|
"""
|
||||||
|
Event handler for the 'hide_combined_quick_error' check box
|
||||||
|
"""
|
||||||
|
self.bible_search_while_typing = (check_state == QtCore.Qt.Checked)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
settings.beginGroup(self.settings_section)
|
settings.beginGroup(self.settings_section)
|
||||||
@ -355,6 +404,12 @@ class BiblesTab(SettingsTab):
|
|||||||
self.end_separator_check_box.setChecked(True)
|
self.end_separator_check_box.setChecked(True)
|
||||||
self.language_selection = settings.value('book name language')
|
self.language_selection = settings.value('book name language')
|
||||||
self.language_selection_combo_box.setCurrentIndex(self.language_selection)
|
self.language_selection_combo_box.setCurrentIndex(self.language_selection)
|
||||||
|
self.reset_to_combined_quick_search = settings.value('reset to combined quick search')
|
||||||
|
self.reset_to_combined_quick_search_check_box.setChecked(self.reset_to_combined_quick_search)
|
||||||
|
self.hide_combined_quick_error = settings.value('hide combined quick error')
|
||||||
|
self.hide_combined_quick_error_check_box.setChecked(self.hide_combined_quick_error)
|
||||||
|
self.bible_search_while_typing = settings.value('is search while typing enabled')
|
||||||
|
self.bible_search_while_typing_check_box.setChecked(self.bible_search_while_typing)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -386,6 +441,9 @@ class BiblesTab(SettingsTab):
|
|||||||
if self.language_selection != settings.value('book name language'):
|
if self.language_selection != settings.value('book name language'):
|
||||||
settings.setValue('book name language', self.language_selection)
|
settings.setValue('book name language', self.language_selection)
|
||||||
self.settings_form.register_post_process('bibles_load_list')
|
self.settings_form.register_post_process('bibles_load_list')
|
||||||
|
settings.setValue('reset to combined quick search', self.reset_to_combined_quick_search)
|
||||||
|
settings.setValue('hide combined quick error', self.hide_combined_quick_error)
|
||||||
|
settings.setValue('is search while typing enabled', self.bible_search_while_typing)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
if self.tab_visited:
|
if self.tab_visited:
|
||||||
self.settings_form.register_post_process('bibles_config_updated')
|
self.settings_form.register_post_process('bibles_config_updated')
|
||||||
|
@ -128,6 +128,12 @@ class BibleDB(Manager, RegistryProperties):
|
|||||||
The name of the database. This is also used as the file name for SQLite databases.
|
The name of the database. This is also used as the file name for SQLite databases.
|
||||||
"""
|
"""
|
||||||
log.info('BibleDB loaded')
|
log.info('BibleDB loaded')
|
||||||
|
self._setup(parent, **kwargs)
|
||||||
|
|
||||||
|
def _setup(self, parent, **kwargs):
|
||||||
|
"""
|
||||||
|
Run some initial setup. This method is separate from __init__ in order to mock it out in tests.
|
||||||
|
"""
|
||||||
self.bible_plugin = parent
|
self.bible_plugin = parent
|
||||||
self.session = None
|
self.session = None
|
||||||
if 'path' not in kwargs:
|
if 'path' not in kwargs:
|
||||||
@ -465,14 +471,13 @@ class BibleDB(Manager, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
log.debug('BibleDB.get_language()')
|
log.debug('BibleDB.get_language()')
|
||||||
from openlp.plugins.bibles.forms import LanguageForm
|
from openlp.plugins.bibles.forms import LanguageForm
|
||||||
language = None
|
language_id = None
|
||||||
language_form = LanguageForm(self.wizard)
|
language_form = LanguageForm(self.wizard)
|
||||||
if language_form.exec(bible_name):
|
if language_form.exec(bible_name):
|
||||||
language = str(language_form.language_combo_box.currentText())
|
combo_box = language_form.language_combo_box
|
||||||
if not language:
|
language_id = combo_box.itemData(combo_box.currentIndex())
|
||||||
|
if not language_id:
|
||||||
return False
|
return False
|
||||||
language = BiblesResourcesDB.get_language(language)
|
|
||||||
language_id = language['id']
|
|
||||||
self.save_meta('language_id', language_id)
|
self.save_meta('language_id', language_id)
|
||||||
return language_id
|
return language_id
|
||||||
|
|
||||||
@ -767,43 +772,6 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||||||
return book[0]
|
return book[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_language(name):
|
|
||||||
"""
|
|
||||||
Return a dict containing the language id, name and code by name or abbreviation.
|
|
||||||
|
|
||||||
:param name: The name or abbreviation of the language.
|
|
||||||
"""
|
|
||||||
log.debug('BiblesResourcesDB.get_language("{name}")'.format(name=name))
|
|
||||||
if not isinstance(name, str):
|
|
||||||
name = str(name)
|
|
||||||
language = BiblesResourcesDB.run_sql(
|
|
||||||
'SELECT id, name, code FROM language WHERE name = ? OR code = ?', (name, name.lower()))
|
|
||||||
if language:
|
|
||||||
return {
|
|
||||||
'id': language[0][0],
|
|
||||||
'name': str(language[0][1]),
|
|
||||||
'code': str(language[0][2])
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_languages():
|
|
||||||
"""
|
|
||||||
Return a dict containing all languages with id, name and code.
|
|
||||||
"""
|
|
||||||
log.debug('BiblesResourcesDB.get_languages()')
|
|
||||||
languages = BiblesResourcesDB.run_sql('SELECT id, name, code FROM language ORDER by name')
|
|
||||||
if languages:
|
|
||||||
return [{
|
|
||||||
'id': language[0],
|
|
||||||
'name': str(language[1]),
|
|
||||||
'code': str(language[2])
|
|
||||||
} for language in languages]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_testament_reference():
|
def get_testament_reference():
|
||||||
"""
|
"""
|
||||||
@ -1014,7 +982,7 @@ class OldBibleDB(QtCore.QObject, Manager):
|
|||||||
|
|
||||||
def get_verses(self, book_id):
|
def get_verses(self, book_id):
|
||||||
"""
|
"""
|
||||||
Returns the verses of the Bible.
|
Returns the verses of the Bible.
|
||||||
"""
|
"""
|
||||||
verses = self.run_sql(
|
verses = self.run_sql(
|
||||||
'SELECT book_id, chapter, verse, text FROM verse WHERE book_id = ? ORDER BY id', (book_id, ))
|
'SELECT book_id, chapter, verse, text FROM verse WHERE book_id = ? ORDER BY id', (book_id, ))
|
||||||
|
@ -252,7 +252,7 @@ class BGExtract(RegistryProperties):
|
|||||||
chapter=chapter,
|
chapter=chapter,
|
||||||
version=version)
|
version=version)
|
||||||
soup = get_soup_for_bible_ref(
|
soup = get_soup_for_bible_ref(
|
||||||
'http://legacy.biblegateway.com/passage/?{url}'.format(url=url_params),
|
'http://biblegateway.com/passage/?{url}'.format(url=url_params),
|
||||||
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
|
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
|
||||||
if not soup:
|
if not soup:
|
||||||
return None
|
return None
|
||||||
@ -281,7 +281,7 @@ class BGExtract(RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
|
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
|
||||||
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
|
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
|
||||||
reference_url = 'http://legacy.biblegateway.com/versions/?{url}#books'.format(url=url_params)
|
reference_url = 'http://biblegateway.com/versions/?{url}#books'.format(url=url_params)
|
||||||
page = get_web_page(reference_url)
|
page = get_web_page(reference_url)
|
||||||
if not page:
|
if not page:
|
||||||
send_error_message('download')
|
send_error_message('download')
|
||||||
@ -312,7 +312,7 @@ class BGExtract(RegistryProperties):
|
|||||||
for book in content:
|
for book in content:
|
||||||
book = book.find('td')
|
book = book.find('td')
|
||||||
if book:
|
if book:
|
||||||
books.append(book.contents[0])
|
books.append(book.contents[1])
|
||||||
return books
|
return books
|
||||||
|
|
||||||
def get_bibles_from_http(self):
|
def get_bibles_from_http(self):
|
||||||
@ -322,11 +322,11 @@ class BGExtract(RegistryProperties):
|
|||||||
returns a list in the form [(biblename, biblekey, language_code)]
|
returns a list in the form [(biblename, biblekey, language_code)]
|
||||||
"""
|
"""
|
||||||
log.debug('BGExtract.get_bibles_from_http')
|
log.debug('BGExtract.get_bibles_from_http')
|
||||||
bible_url = 'https://legacy.biblegateway.com/versions/'
|
bible_url = 'https://biblegateway.com/versions/'
|
||||||
soup = get_soup_for_bible_ref(bible_url)
|
soup = get_soup_for_bible_ref(bible_url)
|
||||||
if not soup:
|
if not soup:
|
||||||
return None
|
return None
|
||||||
bible_select = soup.find('select', {'class': 'translation-dropdown'})
|
bible_select = soup.find('select', {'class': 'search-translation-select'})
|
||||||
if not bible_select:
|
if not bible_select:
|
||||||
log.debug('No select tags found - did site change?')
|
log.debug('No select tags found - did site change?')
|
||||||
return None
|
return None
|
||||||
@ -532,28 +532,26 @@ class CWExtract(RegistryProperties):
|
|||||||
returns a list in the form [(biblename, biblekey, language_code)]
|
returns a list in the form [(biblename, biblekey, language_code)]
|
||||||
"""
|
"""
|
||||||
log.debug('CWExtract.get_bibles_from_http')
|
log.debug('CWExtract.get_bibles_from_http')
|
||||||
bible_url = 'http://www.biblestudytools.com/'
|
bible_url = 'http://www.biblestudytools.com/bible-versions/'
|
||||||
soup = get_soup_for_bible_ref(bible_url)
|
soup = get_soup_for_bible_ref(bible_url)
|
||||||
if not soup:
|
if not soup:
|
||||||
return None
|
return None
|
||||||
bible_select = soup.find('select')
|
h4_tags = soup.find_all('h4', {'class': 'small-header'})
|
||||||
if not bible_select:
|
if not h4_tags:
|
||||||
log.debug('No select tags found - did site change?')
|
log.debug('No h4 tags found - did site change?')
|
||||||
return None
|
|
||||||
option_tags = bible_select.find_all('option', {'class': 'log-translation'})
|
|
||||||
if not option_tags:
|
|
||||||
log.debug('No option tags found - did site change?')
|
|
||||||
return None
|
return None
|
||||||
bibles = []
|
bibles = []
|
||||||
for ot in option_tags:
|
for h4t in h4_tags:
|
||||||
tag_text = ot.get_text().strip()
|
short_name = None
|
||||||
try:
|
if h4t.span:
|
||||||
tag_value = ot['value']
|
short_name = h4t.span.get_text().strip().lower()
|
||||||
except KeyError:
|
else:
|
||||||
log.exception('No value attribute found - did site change?')
|
log.error('No span tag found - did site change?')
|
||||||
return None
|
return None
|
||||||
if not tag_value:
|
if not short_name:
|
||||||
continue
|
continue
|
||||||
|
h4t.span.extract()
|
||||||
|
tag_text = h4t.get_text().strip()
|
||||||
# The names of non-english bibles has their language in parentheses at the end
|
# The names of non-english bibles has their language in parentheses at the end
|
||||||
if tag_text.endswith(')'):
|
if tag_text.endswith(')'):
|
||||||
language = tag_text[tag_text.rfind('(') + 1:-1]
|
language = tag_text[tag_text.rfind('(') + 1:-1]
|
||||||
@ -561,12 +559,20 @@ class CWExtract(RegistryProperties):
|
|||||||
language_code = CROSSWALK_LANGUAGES[language]
|
language_code = CROSSWALK_LANGUAGES[language]
|
||||||
else:
|
else:
|
||||||
language_code = ''
|
language_code = ''
|
||||||
# ... except for the latin vulgate
|
# ... except for those that don't...
|
||||||
elif 'latin' in tag_text.lower():
|
elif 'latin' in tag_text.lower():
|
||||||
language_code = 'la'
|
language_code = 'la'
|
||||||
|
elif 'la biblia' in tag_text.lower() or 'nueva' in tag_text.lower():
|
||||||
|
language_code = 'es'
|
||||||
|
elif 'chinese' in tag_text.lower():
|
||||||
|
language_code = 'zh'
|
||||||
|
elif 'greek' in tag_text.lower():
|
||||||
|
language_code = 'el'
|
||||||
|
elif 'nova' in tag_text.lower():
|
||||||
|
language_code = 'pt'
|
||||||
else:
|
else:
|
||||||
language_code = 'en'
|
language_code = 'en'
|
||||||
bibles.append((tag_text, tag_value, language_code))
|
bibles.append((tag_text, short_name, language_code))
|
||||||
return bibles
|
return bibles
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from openlp.core.common import RegistryProperties, AppLocation, Settings, translate, delete_file
|
from openlp.core.common import RegistryProperties, AppLocation, Settings, translate, delete_file, UiStrings
|
||||||
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
|
from openlp.plugins.bibles.lib import parse_reference, LanguageSelection
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||||
from .csvbible import CSVBible
|
from .csvbible import CSVBible
|
||||||
from .http import HTTPBible
|
from .http import HTTPBible
|
||||||
@ -267,42 +267,21 @@ class BibleManager(RegistryProperties):
|
|||||||
For second bible this is necessary.
|
For second bible this is necessary.
|
||||||
:param show_error:
|
:param show_error:
|
||||||
"""
|
"""
|
||||||
|
# If no bibles are installed, message is given.
|
||||||
log.debug('BibleManager.get_verses("{bible}", "{verse}")'.format(bible=bible, verse=verse_text))
|
log.debug('BibleManager.get_verses("{bible}", "{verse}")'.format(bible=bible, verse=verse_text))
|
||||||
if not bible:
|
if not bible:
|
||||||
if show_error:
|
if show_error:
|
||||||
self.main_window.information_message(
|
self.main_window.information_message(
|
||||||
translate('BiblesPlugin.BibleManager', 'No Bibles Available'),
|
UiStrings().BibleNoBiblesTitle,
|
||||||
translate('BiblesPlugin.BibleManager', 'There are no Bibles currently installed. Please use the '
|
UiStrings().BibleNoBibles)
|
||||||
'Import Wizard to install one or more Bibles.')
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
|
# Get the language for books.
|
||||||
language_selection = self.get_language_selection(bible)
|
language_selection = self.get_language_selection(bible)
|
||||||
ref_list = parse_reference(verse_text, self.db_cache[bible], language_selection, book_ref_id)
|
ref_list = parse_reference(verse_text, self.db_cache[bible], language_selection, book_ref_id)
|
||||||
if ref_list:
|
if ref_list:
|
||||||
return self.db_cache[bible].get_verses(ref_list, show_error)
|
return self.db_cache[bible].get_verses(ref_list, show_error)
|
||||||
|
# If nothing is found. Message is given if this is not combined search. (defined in mediaitem.py)
|
||||||
else:
|
else:
|
||||||
if show_error:
|
|
||||||
reference_separators = {
|
|
||||||
'verse': get_reference_separator('sep_v_display'),
|
|
||||||
'range': get_reference_separator('sep_r_display'),
|
|
||||||
'list': get_reference_separator('sep_l_display')}
|
|
||||||
self.main_window.information_message(
|
|
||||||
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
|
||||||
translate('BiblesPlugin.BibleManager', 'Your scripture reference is either not supported by '
|
|
||||||
'OpenLP or is invalid. Please make sure your reference '
|
|
||||||
'conforms to one of the following patterns or consult the manual:\n\n'
|
|
||||||
'Book Chapter\n'
|
|
||||||
'Book Chapter%(range)sChapter\n'
|
|
||||||
'Book Chapter%(verse)sVerse%(range)sVerse\n'
|
|
||||||
'Book Chapter%(verse)sVerse%(range)sVerse%(list)sVerse'
|
|
||||||
'%(range)sVerse\n'
|
|
||||||
'Book Chapter%(verse)sVerse%(range)sVerse%(list)sChapter'
|
|
||||||
'%(verse)sVerse%(range)sVerse\n'
|
|
||||||
'Book Chapter%(verse)sVerse%(range)sChapter%(verse)sVerse',
|
|
||||||
'Please pay attention to the appended "s" of the wildcards '
|
|
||||||
'and refrain from translating the words inside the names in the brackets.')
|
|
||||||
% reference_separators
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_language_selection(self, bible):
|
def get_language_selection(self, bible):
|
||||||
@ -334,13 +313,11 @@ class BibleManager(RegistryProperties):
|
|||||||
:param text: The text to search for (unicode).
|
:param text: The text to search for (unicode).
|
||||||
"""
|
"""
|
||||||
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
|
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
|
||||||
|
# If no bibles are installed, message is given.
|
||||||
if not bible:
|
if not bible:
|
||||||
self.main_window.information_message(
|
self.main_window.information_message(
|
||||||
translate('BiblesPlugin.BibleManager', 'No Bibles Available'),
|
UiStrings().BibleNoBiblesTitle,
|
||||||
translate('BiblesPlugin.BibleManager',
|
UiStrings().BibleNoBibles)
|
||||||
'There are no Bibles currently installed. Please use the Import Wizard to install one or '
|
|
||||||
'more Bibles.')
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
# Check if the bible or second_bible is a web bible.
|
# Check if the bible or second_bible is a web bible.
|
||||||
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
|
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
|
||||||
@ -348,20 +325,56 @@ class BibleManager(RegistryProperties):
|
|||||||
if second_bible:
|
if second_bible:
|
||||||
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
||||||
if web_bible or second_web_bible:
|
if web_bible or second_web_bible:
|
||||||
|
# If either Bible is Web, cursor is reset to normal and message is given.
|
||||||
|
self.application.set_normal_cursor()
|
||||||
self.main_window.information_message(
|
self.main_window.information_message(
|
||||||
translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used'),
|
translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used in Text Search'),
|
||||||
translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.')
|
translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.\n'
|
||||||
|
'Please use the Scripture Reference Search instead.\n\n'
|
||||||
|
'This means that the currently used Bible\nor Second Bible '
|
||||||
|
'is installed as Web Bible.\n\n'
|
||||||
|
'If you were trying to perform a Reference search\nin Combined '
|
||||||
|
'Search, your reference is invalid.')
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
if text:
|
# Shorter than 3 char searches break OpenLP with very long search times, thus they are blocked.
|
||||||
|
if len(text) - text.count(' ') < 3:
|
||||||
|
return None
|
||||||
|
# Fetch the results from db. If no results are found, return None, no message is given for this.
|
||||||
|
elif text:
|
||||||
|
return self.db_cache[bible].verse_search(text)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def verse_search_while_typing(self, bible, second_bible, text):
|
||||||
|
"""
|
||||||
|
Does a verse search for the given bible and text.
|
||||||
|
This is used during "Search while typing"
|
||||||
|
It's the same thing as the normal text search, but it does not show the web Bible error.
|
||||||
|
(It would result in the error popping every time a char is entered or removed)
|
||||||
|
It also does not have a minimum text len, this is set in mediaitem.py
|
||||||
|
|
||||||
|
:param bible: The bible to search in (unicode).
|
||||||
|
:param second_bible: The second bible (unicode). We do not search in this bible.
|
||||||
|
:param text: The text to search for (unicode).
|
||||||
|
"""
|
||||||
|
# If no bibles are installed, message is given.
|
||||||
|
if not bible:
|
||||||
|
return None
|
||||||
|
# Check if the bible or second_bible is a web bible.
|
||||||
|
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
|
||||||
|
second_web_bible = ''
|
||||||
|
if second_bible:
|
||||||
|
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
||||||
|
if web_bible or second_web_bible:
|
||||||
|
# If either Bible is Web, cursor is reset to normal and search ends w/o any message.
|
||||||
|
self.check_search_result()
|
||||||
|
self.application.set_normal_cursor()
|
||||||
|
return None
|
||||||
|
# Fetch the results from db. If no results are found, return None, no message is given for this.
|
||||||
|
elif text:
|
||||||
return self.db_cache[bible].verse_search(text)
|
return self.db_cache[bible].verse_search(text)
|
||||||
else:
|
else:
|
||||||
self.main_window.information_message(
|
|
||||||
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
|
||||||
translate('BiblesPlugin.BibleManager', 'You did not enter a search keyword.\nYou can separate '
|
|
||||||
'different keywords by a space to search for all of your keywords and you can separate '
|
|
||||||
'them by a comma to search for one of them.')
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def save_meta_data(self, bible, version, copyright, permissions, book_name_language=None):
|
def save_meta_data(self, bible, version, copyright, permissions, book_name_language=None):
|
||||||
|
@ -35,6 +35,7 @@ from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
|
|||||||
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \
|
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \
|
||||||
LanguageSelection, BibleStrings
|
LanguageSelection, BibleStrings
|
||||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||||
|
import re
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ class BibleSearch(object):
|
|||||||
"""
|
"""
|
||||||
Reference = 1
|
Reference = 1
|
||||||
Text = 2
|
Text = 2
|
||||||
|
Combined = 3
|
||||||
|
|
||||||
|
|
||||||
class BibleMediaItem(MediaManagerItem):
|
class BibleMediaItem(MediaManagerItem):
|
||||||
@ -56,6 +58,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
log.info('Bible Media Item loaded')
|
log.info('Bible Media Item loaded')
|
||||||
|
|
||||||
def __init__(self, parent, plugin):
|
def __init__(self, parent, plugin):
|
||||||
|
self.clear_icon = build_icon(':/bibles/bibles_search_clear.png')
|
||||||
self.lock_icon = build_icon(':/bibles/bibles_search_lock.png')
|
self.lock_icon = build_icon(':/bibles/bibles_search_lock.png')
|
||||||
self.unlock_icon = build_icon(':/bibles/bibles_search_unlock.png')
|
self.unlock_icon = build_icon(':/bibles/bibles_search_unlock.png')
|
||||||
MediaManagerItem.__init__(self, parent, plugin)
|
MediaManagerItem.__init__(self, parent, plugin)
|
||||||
@ -157,10 +160,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
search_button_layout = QtWidgets.QHBoxLayout()
|
search_button_layout = QtWidgets.QHBoxLayout()
|
||||||
search_button_layout.setObjectName(prefix + 'search_button_layout')
|
search_button_layout.setObjectName(prefix + 'search_button_layout')
|
||||||
search_button_layout.addStretch()
|
search_button_layout.addStretch()
|
||||||
|
# Note: If we use QPushButton instead of the QToolButton, the icon will be larger than the Lock icon.
|
||||||
|
clear_button = QtWidgets.QToolButton(tab)
|
||||||
|
clear_button.setIcon(self.clear_icon)
|
||||||
|
clear_button.setObjectName(prefix + 'ClearButton')
|
||||||
lock_button = QtWidgets.QToolButton(tab)
|
lock_button = QtWidgets.QToolButton(tab)
|
||||||
lock_button.setIcon(self.unlock_icon)
|
lock_button.setIcon(self.unlock_icon)
|
||||||
lock_button.setCheckable(True)
|
lock_button.setCheckable(True)
|
||||||
lock_button.setObjectName(prefix + 'LockButton')
|
lock_button.setObjectName(prefix + 'LockButton')
|
||||||
|
search_button_layout.addWidget(clear_button)
|
||||||
search_button_layout.addWidget(lock_button)
|
search_button_layout.addWidget(lock_button)
|
||||||
search_button = QtWidgets.QPushButton(tab)
|
search_button = QtWidgets.QPushButton(tab)
|
||||||
search_button.setObjectName(prefix + 'SearchButton')
|
search_button.setObjectName(prefix + 'SearchButton')
|
||||||
@ -176,6 +184,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
setattr(self, prefix + 'SecondComboBox', second_combo_box)
|
setattr(self, prefix + 'SecondComboBox', second_combo_box)
|
||||||
setattr(self, prefix + 'StyleLabel', style_label)
|
setattr(self, prefix + 'StyleLabel', style_label)
|
||||||
setattr(self, prefix + 'StyleComboBox', style_combo_box)
|
setattr(self, prefix + 'StyleComboBox', style_combo_box)
|
||||||
|
setattr(self, prefix + 'ClearButton', clear_button)
|
||||||
setattr(self, prefix + 'LockButton', lock_button)
|
setattr(self, prefix + 'LockButton', lock_button)
|
||||||
setattr(self, prefix + 'SearchButtonLayout', search_button_layout)
|
setattr(self, prefix + 'SearchButtonLayout', search_button_layout)
|
||||||
setattr(self, prefix + 'SearchButton', search_button)
|
setattr(self, prefix + 'SearchButton', search_button)
|
||||||
@ -245,11 +254,14 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.quickStyleComboBox.activated.connect(self.on_quick_style_combo_box_changed)
|
self.quickStyleComboBox.activated.connect(self.on_quick_style_combo_box_changed)
|
||||||
self.advancedStyleComboBox.activated.connect(self.on_advanced_style_combo_box_changed)
|
self.advancedStyleComboBox.activated.connect(self.on_advanced_style_combo_box_changed)
|
||||||
# Buttons
|
# Buttons
|
||||||
|
self.advancedClearButton.clicked.connect(self.on_clear_button)
|
||||||
|
self.quickClearButton.clicked.connect(self.on_clear_button)
|
||||||
self.advancedSearchButton.clicked.connect(self.on_advanced_search_button)
|
self.advancedSearchButton.clicked.connect(self.on_advanced_search_button)
|
||||||
self.quickSearchButton.clicked.connect(self.on_quick_search_button)
|
self.quickSearchButton.clicked.connect(self.on_quick_search_button)
|
||||||
# Other stuff
|
# Other stuff
|
||||||
self.quick_search_edit.returnPressed.connect(self.on_quick_search_button)
|
self.quick_search_edit.returnPressed.connect(self.on_quick_search_button)
|
||||||
self.search_tab_bar.currentChanged.connect(self.on_search_tab_bar_current_changed)
|
self.search_tab_bar.currentChanged.connect(self.on_search_tab_bar_current_changed)
|
||||||
|
self.quick_search_edit.textChanged.connect(self.on_search_text_edit_changed)
|
||||||
|
|
||||||
def on_focus(self):
|
def on_focus(self):
|
||||||
if self.quickTab.isVisible():
|
if self.quickTab.isVisible():
|
||||||
@ -286,6 +298,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||||
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
||||||
self.quickStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
self.quickStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
||||||
|
self.quickClearButton.setToolTip(translate('BiblesPlugin.MediaItem', 'Clear the search results.'))
|
||||||
self.quickLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
self.quickLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
||||||
'Toggle to keep or clear the previous results.'))
|
'Toggle to keep or clear the previous results.'))
|
||||||
self.quickSearchButton.setText(UiStrings().Search)
|
self.quickSearchButton.setText(UiStrings().Search)
|
||||||
@ -300,6 +313,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||||
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
||||||
self.advancedStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
self.advancedStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
||||||
|
self.advancedClearButton.setToolTip(translate('BiblesPlugin.MediaItem', 'Clear the search results.'))
|
||||||
self.advancedLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
self.advancedLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
||||||
'Toggle to keep or clear the previous results.'))
|
'Toggle to keep or clear the previous results.'))
|
||||||
self.advancedSearchButton.setText(UiStrings().Search)
|
self.advancedSearchButton.setText(UiStrings().Search)
|
||||||
@ -309,6 +323,9 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.plugin.manager.media = self
|
self.plugin.manager.media = self
|
||||||
self.load_bibles()
|
self.load_bibles()
|
||||||
self.quick_search_edit.set_search_types([
|
self.quick_search_edit.set_search_types([
|
||||||
|
(BibleSearch.Combined, ':/bibles/bibles_search_combined.png',
|
||||||
|
translate('BiblesPlugin.MediaItem', 'Text or Reference'),
|
||||||
|
translate('BiblesPlugin.MediaItem', 'Text or Reference...')),
|
||||||
(BibleSearch.Reference, ':/bibles/bibles_search_reference.png',
|
(BibleSearch.Reference, ':/bibles/bibles_search_reference.png',
|
||||||
translate('BiblesPlugin.MediaItem', 'Scripture Reference'),
|
translate('BiblesPlugin.MediaItem', 'Scripture Reference'),
|
||||||
translate('BiblesPlugin.MediaItem', 'Search Scripture Reference...')),
|
translate('BiblesPlugin.MediaItem', 'Search Scripture Reference...')),
|
||||||
@ -424,18 +441,24 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
def update_auto_completer(self):
|
def update_auto_completer(self):
|
||||||
"""
|
"""
|
||||||
This updates the bible book completion list for the search field. The completion depends on the bible. It is
|
This updates the bible book completion list for the search field. The completion depends on the bible. It is
|
||||||
only updated when we are doing a reference search, otherwise the auto completion list is removed.
|
only updated when we are doing reference or combined search, in text search the completion list is removed.
|
||||||
"""
|
"""
|
||||||
log.debug('update_auto_completer')
|
log.debug('update_auto_completer')
|
||||||
# Save the current search type to the configuration.
|
# Save the current search type to the configuration. If setting for automatically resetting the search type to
|
||||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
# Combined is enabled, use that otherwise use the currently selected search type.
|
||||||
self.quick_search_edit.current_search_type())
|
# Note: This setting requires a restart to take effect.
|
||||||
|
if Settings().value(self.settings_section + '/reset to combined quick search'):
|
||||||
|
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||||
|
BibleSearch.Combined)
|
||||||
|
else:
|
||||||
|
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||||
|
self.quick_search_edit.current_search_type())
|
||||||
# Save the current bible to the configuration.
|
# Save the current bible to the configuration.
|
||||||
Settings().setValue('{section}/quick bible'.format(section=self.settings_section),
|
Settings().setValue('{section}/quick bible'.format(section=self.settings_section),
|
||||||
self.quickVersionComboBox.currentText())
|
self.quickVersionComboBox.currentText())
|
||||||
books = []
|
books = []
|
||||||
# We have to do a 'Reference Search'.
|
# We have to do a 'Reference Search' (Or as part of Combined Search).
|
||||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
if self.quick_search_edit.current_search_type() is not BibleSearch.Text:
|
||||||
bibles = self.plugin.manager.get_bibles()
|
bibles = self.plugin.manager.get_bibles()
|
||||||
bible = self.quickVersionComboBox.currentText()
|
bible = self.quickVersionComboBox.currentText()
|
||||||
if bible:
|
if bible:
|
||||||
@ -525,7 +548,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.advancedTab.setVisible(True)
|
self.advancedTab.setVisible(True)
|
||||||
self.advanced_book_combo_box.setFocus()
|
self.advanced_book_combo_box.setFocus()
|
||||||
|
|
||||||
|
def on_clear_button(self):
|
||||||
|
# Clear the list, then set the "No search Results" message, then clear the text field and give it focus.
|
||||||
|
self.list_view.clear()
|
||||||
|
self.check_search_result()
|
||||||
|
self.quick_search_edit.clear()
|
||||||
|
self.quick_search_edit.setFocus()
|
||||||
|
|
||||||
def on_lock_button_toggled(self, checked):
|
def on_lock_button_toggled(self, checked):
|
||||||
|
self.quick_search_edit.setFocus()
|
||||||
if checked:
|
if checked:
|
||||||
self.sender().setIcon(self.lock_icon)
|
self.sender().setIcon(self.lock_icon)
|
||||||
else:
|
else:
|
||||||
@ -652,10 +683,120 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.check_search_result()
|
self.check_search_result()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
|
def on_quick_reference_search(self):
|
||||||
|
"""
|
||||||
|
We are doing a 'Reference Search'.
|
||||||
|
This search is called on def on_quick_search_button by Quick Reference and Combined Searches.
|
||||||
|
"""
|
||||||
|
# Set Bibles to use the text input from Quick search field.
|
||||||
|
bible = self.quickVersionComboBox.currentText()
|
||||||
|
second_bible = self.quickSecondComboBox.currentText()
|
||||||
|
"""
|
||||||
|
Get input from field and replace 'A-Z + . ' with ''
|
||||||
|
This will check if field has any '.' after A-Z and removes them. Eg. Gen. 1 = Ge 1 = Genesis 1
|
||||||
|
If Book name has '.' after number. eg. 1. Genesis, the search fails without the dot, and vice versa.
|
||||||
|
A better solution would be to make '.' optional in the search results. Current solution was easier to code.
|
||||||
|
"""
|
||||||
|
text = self.quick_search_edit.text()
|
||||||
|
text = re.sub('\D[.]\s', ' ', text)
|
||||||
|
# This is triggered on reference search, use the search from manager.py
|
||||||
|
if self.quick_search_edit.current_search_type() != BibleSearch.Text:
|
||||||
|
self.search_results = self.plugin.manager.get_verses(bible, text)
|
||||||
|
if second_bible and self.search_results:
|
||||||
|
self.second_search_results = \
|
||||||
|
self.plugin.manager.get_verses(second_bible, text, self.search_results[0].book.book_reference_id)
|
||||||
|
|
||||||
|
def on_quick_text_search(self):
|
||||||
|
"""
|
||||||
|
We are doing a 'Text Search'.
|
||||||
|
This search is called on def on_quick_search_button by Quick Text and Combined Searches.
|
||||||
|
"""
|
||||||
|
# Set Bibles to use the text input from Quick search field.
|
||||||
|
bible = self.quickVersionComboBox.currentText()
|
||||||
|
second_bible = self.quickSecondComboBox.currentText()
|
||||||
|
text = self.quick_search_edit.text()
|
||||||
|
# If Text search ends with "," OpenLP will crash, prevent this from happening by removing all ","s.
|
||||||
|
text = re.sub('[,]', '', text)
|
||||||
|
self.application.set_busy_cursor()
|
||||||
|
# Get Bibles list
|
||||||
|
bibles = self.plugin.manager.get_bibles()
|
||||||
|
# Add results to "search_results"
|
||||||
|
self.search_results = self.plugin.manager.verse_search(bible, second_bible, text)
|
||||||
|
if second_bible and self.search_results:
|
||||||
|
# new_search_results is needed to make sure 2nd bible contains all verses. (And counting them on error)
|
||||||
|
text = []
|
||||||
|
new_search_results = []
|
||||||
|
count = 0
|
||||||
|
passage_not_found = False
|
||||||
|
# Search second bible for results of search_results to make sure everythigns there.
|
||||||
|
# Count all the unfound passages.
|
||||||
|
for verse in self.search_results:
|
||||||
|
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
||||||
|
if not db_book:
|
||||||
|
log.debug('Passage "{name} {chapter:d}:{verse:d}" not found in '
|
||||||
|
'Second Bible'.format(name=verse.book.name, chapter=verse.chapter, verse=verse.verse))
|
||||||
|
passage_not_found = True
|
||||||
|
count += 1
|
||||||
|
continue
|
||||||
|
new_search_results.append(verse)
|
||||||
|
text.append((verse.book.book_reference_id, verse.chapter, verse.verse, verse.verse))
|
||||||
|
if passage_not_found:
|
||||||
|
# This is for the 2nd Bible.
|
||||||
|
self.main_window.information_message(
|
||||||
|
translate('BiblesPlugin.MediaItem', 'Information'),
|
||||||
|
translate('BiblesPlugin.MediaItem', 'The second Bible does not contain all the verses '
|
||||||
|
'that are in the main Bible.\nOnly verses found in both Bibles'
|
||||||
|
' will be shown.\n\n{count:d} verses have not been included '
|
||||||
|
'in the results.').format(count=count))
|
||||||
|
# Join the searches so only verses that are found on both Bibles are shown.
|
||||||
|
self.search_results = new_search_results
|
||||||
|
self.second_search_results = bibles[second_bible].get_verses(text)
|
||||||
|
|
||||||
|
def on_quick_text_search_while_typing(self):
|
||||||
|
"""
|
||||||
|
We are doing a 'Text Search' while typing
|
||||||
|
Call the verse_search_while_typing from manager.py
|
||||||
|
It does not show web bible errors while typing.
|
||||||
|
(It would result in the error popping every time a char is entered or removed)
|
||||||
|
"""
|
||||||
|
# Set Bibles to use the text input from Quick search field.
|
||||||
|
bible = self.quickVersionComboBox.currentText()
|
||||||
|
second_bible = self.quickSecondComboBox.currentText()
|
||||||
|
text = self.quick_search_edit.text()
|
||||||
|
# If Text search ends with "," OpenLP will crash, prevent this from happening by removing all ","s.
|
||||||
|
text = re.sub('[,]', '', text)
|
||||||
|
self.application.set_busy_cursor()
|
||||||
|
# Get Bibles list
|
||||||
|
bibles = self.plugin.manager.get_bibles()
|
||||||
|
# Add results to "search_results"
|
||||||
|
self.search_results = self.plugin.manager.verse_search_while_typing(bible, second_bible, text)
|
||||||
|
if second_bible and self.search_results:
|
||||||
|
# new_search_results is needed to make sure 2nd bible contains all verses. (And counting them on error)
|
||||||
|
text = []
|
||||||
|
new_search_results = []
|
||||||
|
count = 0
|
||||||
|
passage_not_found = False
|
||||||
|
# Search second bible for results of search_results to make sure everythigns there.
|
||||||
|
# Count all the unfound passages. Even thou no error is shown, this needs to be done or
|
||||||
|
# the code breaks later on.
|
||||||
|
for verse in self.search_results:
|
||||||
|
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
||||||
|
if not db_book:
|
||||||
|
log.debug('Passage ("{versebookname}","{versechapter}","{verseverse}") not found in Second Bible'
|
||||||
|
.format(versebookname=verse.book.name, versechapter='verse.chapter',
|
||||||
|
verseverse=verse.verse))
|
||||||
|
count += 1
|
||||||
|
continue
|
||||||
|
new_search_results.append(verse)
|
||||||
|
text.append((verse.book.book_reference_id, verse.chapter, verse.verse, verse.verse))
|
||||||
|
# Join the searches so only verses that are found on both Bibles are shown.
|
||||||
|
self.search_results = new_search_results
|
||||||
|
self.second_search_results = bibles[second_bible].get_verses(text)
|
||||||
|
|
||||||
def on_quick_search_button(self):
|
def on_quick_search_button(self):
|
||||||
"""
|
"""
|
||||||
Does a quick search and saves the search results. Quick search can either be "Reference Search" or
|
This triggers the proper Quick search based on which search type is used.
|
||||||
"Text Search".
|
"Eg. "Reference Search", "Text Search" or "Combined search".
|
||||||
"""
|
"""
|
||||||
log.debug('Quick Search Button clicked')
|
log.debug('Quick Search Button clicked')
|
||||||
self.quickSearchButton.setEnabled(False)
|
self.quickSearchButton.setEnabled(False)
|
||||||
@ -664,41 +805,68 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
second_bible = self.quickSecondComboBox.currentText()
|
second_bible = self.quickSecondComboBox.currentText()
|
||||||
text = self.quick_search_edit.text()
|
text = self.quick_search_edit.text()
|
||||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||||
# We are doing a 'Reference Search'.
|
# We are doing a 'Reference Search'. (Get script from def on_quick_reference_search)
|
||||||
self.search_results = self.plugin.manager.get_verses(bible, text)
|
self.on_quick_reference_search()
|
||||||
if second_bible and self.search_results:
|
# Get reference separators from settings.
|
||||||
self.second_search_results = \
|
if not self.search_results:
|
||||||
self.plugin.manager.get_verses(second_bible, text, self.search_results[0].book.book_reference_id)
|
reference_separators = {
|
||||||
else:
|
'verse': get_reference_separator('sep_v_display'),
|
||||||
# We are doing a 'Text Search'.
|
'range': get_reference_separator('sep_r_display'),
|
||||||
self.application.set_busy_cursor()
|
'list': get_reference_separator('sep_l_display')}
|
||||||
bibles = self.plugin.manager.get_bibles()
|
self.main_window.information_message(
|
||||||
self.search_results = self.plugin.manager.verse_search(bible, second_bible, text)
|
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
||||||
if second_bible and self.search_results:
|
translate('BiblesPlugin.BibleManager', '<strong>OpenLP couldn’t find anything '
|
||||||
text = []
|
'with your search.<br><br>'
|
||||||
new_search_results = []
|
'Please make sure that your reference follows '
|
||||||
count = 0
|
'one of these patterns:</strong><br><br>%s'
|
||||||
passage_not_found = False
|
% UiStrings().BibleScriptureError % reference_separators))
|
||||||
for verse in self.search_results:
|
elif self.quick_search_edit.current_search_type() == BibleSearch.Text:
|
||||||
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
# We are doing a 'Text Search'. (Get script from def on_quick_text_search)
|
||||||
if not db_book:
|
self.on_quick_text_search()
|
||||||
log.debug('Passage "{name} {chapter:d}:{verse:d}" not found in '
|
if not self.search_results and len(text) - text.count(' ') < 3 and bible:
|
||||||
'Second Bible'.format(name=verse.book.name, chapter=verse.chapter, verse=verse.verse))
|
self.main_window.information_message(
|
||||||
passage_not_found = True
|
UiStrings().BibleShortSearchTitle,
|
||||||
count += 1
|
UiStrings().BibleShortSearch)
|
||||||
continue
|
elif self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||||
new_search_results.append(verse)
|
# We are doing a 'Combined search'. Starting with reference search.
|
||||||
text.append((verse.book.book_reference_id, verse.chapter, verse.verse, verse.verse))
|
# Perform only if text contains any numbers
|
||||||
if passage_not_found:
|
if (char.isdigit() for char in text):
|
||||||
QtWidgets.QMessageBox.information(
|
self.on_quick_reference_search()
|
||||||
self, translate('BiblesPlugin.MediaItem', 'Information'),
|
"""
|
||||||
translate('BiblesPlugin.MediaItem',
|
If results are found, search will be finalized.
|
||||||
'The second Bible does not contain all the verses that are in the main Bible. '
|
This check needs to be here in order to avoid duplicate errors.
|
||||||
'Only verses found in both Bibles will be shown. {count:d} verses have not been '
|
If keyword is shorter than 3 (not including spaces), message is given. It's actually possible to find
|
||||||
'included in the results.').format(count=count),
|
verses with less than 3 chars (Eg. G1 = Genesis 1) thus this error is not shown if any results are found.
|
||||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
if no Bibles are installed, this message is not shown - "No bibles" message is shown instead.
|
||||||
self.search_results = new_search_results
|
"""
|
||||||
self.second_search_results = bibles[second_bible].get_verses(text)
|
if not self.search_results and len(text) - text.count(' ') < 3 and bible:
|
||||||
|
self.main_window.information_message(
|
||||||
|
UiStrings().BibleShortSearchTitle,
|
||||||
|
UiStrings().BibleShortSearch)
|
||||||
|
if not self.search_results and len(text) - text.count(' ') > 2 and bible:
|
||||||
|
# Text search starts here if no reference was found and keyword is longer than 2.
|
||||||
|
# > 2 check is required in order to avoid duplicate error messages for short keywords.
|
||||||
|
self.on_quick_text_search()
|
||||||
|
if not self.search_results and not \
|
||||||
|
Settings().value(self.settings_section + '/hide combined quick error'):
|
||||||
|
self.application.set_normal_cursor()
|
||||||
|
# Reference separators need to be defined both, in here and on reference search,
|
||||||
|
# error won't work if they are left out from one.
|
||||||
|
reference_separators = {
|
||||||
|
'verse': get_reference_separator('sep_v_display'),
|
||||||
|
'range': get_reference_separator('sep_r_display'),
|
||||||
|
'list': get_reference_separator('sep_l_display')}
|
||||||
|
self.main_window.information_message(translate('BiblesPlugin.BibleManager', 'Nothing found'),
|
||||||
|
translate('BiblesPlugin.BibleManager',
|
||||||
|
'<strong>OpenLP couldn’t find anything with your'
|
||||||
|
' search.</strong><br><br>If you tried to search'
|
||||||
|
' with Scripture Reference, please make<br> sure'
|
||||||
|
' that your reference follows one of these'
|
||||||
|
' patterns: <br><br>%s'
|
||||||
|
% UiStrings().BibleScriptureError %
|
||||||
|
reference_separators))
|
||||||
|
# Finalizing the search
|
||||||
|
# List is cleared if not locked, results are listed, button is set available, cursor is set to normal.
|
||||||
if not self.quickLockButton.isChecked():
|
if not self.quickLockButton.isChecked():
|
||||||
self.list_view.clear()
|
self.list_view.clear()
|
||||||
if self.list_view.count() != 0 and self.search_results:
|
if self.list_view.count() != 0 and self.search_results:
|
||||||
@ -709,6 +877,99 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.check_search_result()
|
self.check_search_result()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
|
def on_quick_search_while_typing(self):
|
||||||
|
"""
|
||||||
|
This function is called when "Search as you type" is enabled for Bibles.
|
||||||
|
It is basically the same thing as "on_quick_search_search" but all the error messages are removed.
|
||||||
|
This also has increased min len for text search for performance reasons.
|
||||||
|
For commented version, please visit def on_quick_search_button.
|
||||||
|
"""
|
||||||
|
bible = self.quickVersionComboBox.currentText()
|
||||||
|
second_bible = self.quickSecondComboBox.currentText()
|
||||||
|
text = self.quick_search_edit.text()
|
||||||
|
if self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||||
|
# If text has no numbers, auto search limit is min 8 characters for performance reasons.
|
||||||
|
# If you change this value, also change it in biblestab.py (Count) in enabling search while typing.
|
||||||
|
if (char.isdigit() for char in text) and len(text) > 2:
|
||||||
|
self.on_quick_reference_search()
|
||||||
|
if not self.search_results and len(text) > 7:
|
||||||
|
self.on_quick_text_search_while_typing()
|
||||||
|
elif self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||||
|
self.on_quick_reference_search()
|
||||||
|
elif self.quick_search_edit.current_search_type() == BibleSearch.Text:
|
||||||
|
if len(text) > 7:
|
||||||
|
self.on_quick_text_search_while_typing()
|
||||||
|
if not self.quickLockButton.isChecked():
|
||||||
|
self.list_view.clear()
|
||||||
|
if self.list_view.count() != 0 and self.search_results:
|
||||||
|
self.__check_second_bible(bible, second_bible)
|
||||||
|
elif self.search_results:
|
||||||
|
self.display_results(bible, second_bible)
|
||||||
|
self.check_search_result()
|
||||||
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
|
def on_search_text_edit_changed(self):
|
||||||
|
"""
|
||||||
|
If search automatically while typing is enabled, perform the search and list results when conditions are met.
|
||||||
|
"""
|
||||||
|
if Settings().value('bibles/is search while typing enabled'):
|
||||||
|
text = self.quick_search_edit.text()
|
||||||
|
"""
|
||||||
|
Use Regex for finding space + number in reference search and space + 2 characters in text search.
|
||||||
|
Also search for two characters (Searches require at least two sets of two characters)
|
||||||
|
These are used to prevent bad search queries from starting. (Long/crashing queries)
|
||||||
|
"""
|
||||||
|
space_and_digit_reference = re.compile(' \d')
|
||||||
|
two_chars_text = re.compile('\S\S')
|
||||||
|
space_and_two_chars_text = re.compile(' \S\S')
|
||||||
|
# Turn this into a format that may be used in if statement.
|
||||||
|
count_space_digit_reference = space_and_digit_reference.findall(text)
|
||||||
|
count_two_chars_text = two_chars_text.findall(text)
|
||||||
|
count_spaces_two_chars_text = space_and_two_chars_text.findall(text)
|
||||||
|
"""
|
||||||
|
The Limit is required for setting the proper "No items found" message.
|
||||||
|
"Limit" is also hard coded to on_quick_search_while_typing, it must be there to avoid bad search
|
||||||
|
performance. Limit 8 = Text search, 3 = Reference search.
|
||||||
|
"""
|
||||||
|
limit = 8
|
||||||
|
if self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||||
|
if len(count_space_digit_reference) != 0:
|
||||||
|
limit = 3
|
||||||
|
elif self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||||
|
limit = 3
|
||||||
|
"""
|
||||||
|
If text is empty, clear the list.
|
||||||
|
else: Start by checking if the search is suitable for "Search while typing"
|
||||||
|
"""
|
||||||
|
if len(text) == 0:
|
||||||
|
if not self.quickLockButton.isChecked():
|
||||||
|
self.list_view.clear()
|
||||||
|
self.check_search_result()
|
||||||
|
else:
|
||||||
|
if limit == 3 and (len(text) < limit or len(count_space_digit_reference) == 0):
|
||||||
|
if not self.quickLockButton.isChecked():
|
||||||
|
self.list_view.clear()
|
||||||
|
self.check_search_result()
|
||||||
|
elif (limit == 8 and (len(text) < limit or len(count_spaces_two_chars_text) == 0 or
|
||||||
|
len(count_two_chars_text) < 2)):
|
||||||
|
if not self.quickLockButton.isChecked():
|
||||||
|
self.list_view.clear()
|
||||||
|
self.check_search_result_search_while_typing_short()
|
||||||
|
else:
|
||||||
|
"""
|
||||||
|
Start search if no chars are entered or deleted for 0.2 s
|
||||||
|
If no Timer is set, Text search will break the search by sending repeative search Quaries on
|
||||||
|
all chars. Use the self.on_quick_search_while_typing, this does not contain any error messages.
|
||||||
|
"""
|
||||||
|
self.search_timer = ()
|
||||||
|
if self.search_timer:
|
||||||
|
self.search_timer.stop()
|
||||||
|
self.search_timer.deleteLater()
|
||||||
|
self.search_timer = QtCore.QTimer()
|
||||||
|
self.search_timer.timeout.connect(self.on_quick_search_while_typing)
|
||||||
|
self.search_timer.setSingleShot(True)
|
||||||
|
self.search_timer.start(200)
|
||||||
|
|
||||||
def display_results(self, bible, second_bible=''):
|
def display_results(self, bible, second_bible=''):
|
||||||
"""
|
"""
|
||||||
Displays the search results in the media manager. All data needed for further action is saved for/in each row.
|
Displays the search results in the media manager. All data needed for further action is saved for/in each row.
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import logging
|
import logging
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from openlp.core.common import translate, trace_error_handler
|
from openlp.core.common import languages, translate, trace_error_handler
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
|
|
||||||
@ -62,9 +62,11 @@ class OSISBible(BibleDB):
|
|||||||
namespace = {'ns': 'http://www.bibletechnologies.net/2003/OSIS/namespace'}
|
namespace = {'ns': 'http://www.bibletechnologies.net/2003/OSIS/namespace'}
|
||||||
# Find bible language
|
# Find bible language
|
||||||
language_id = None
|
language_id = None
|
||||||
language = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=namespace)
|
lang = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=namespace)
|
||||||
if language:
|
if lang:
|
||||||
language_id = BiblesResourcesDB.get_language(language[0])
|
language = languages.get_language(lang[0])
|
||||||
|
if hasattr(language, 'id'):
|
||||||
|
language_id = language.id
|
||||||
# The language couldn't be detected, ask the user
|
# The language couldn't be detected, ask the user
|
||||||
if not language_id:
|
if not language_id:
|
||||||
language_id = self.get_language(bible_name)
|
language_id = self.get_language(bible_name)
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import logging
|
import logging
|
||||||
from pysword import modules
|
from pysword import modules
|
||||||
|
|
||||||
from openlp.core.common import translate
|
from openlp.core.common import languages, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||||
|
|
||||||
@ -57,9 +57,12 @@ class SwordBible(BibleDB):
|
|||||||
pysword_modules = modules.SwordModules(self.sword_path)
|
pysword_modules = modules.SwordModules(self.sword_path)
|
||||||
pysword_module_json = pysword_modules.parse_modules()[self.sword_key]
|
pysword_module_json = pysword_modules.parse_modules()[self.sword_key]
|
||||||
bible = pysword_modules.get_bible_from_module(self.sword_key)
|
bible = pysword_modules.get_bible_from_module(self.sword_key)
|
||||||
|
language_id = None
|
||||||
language = pysword_module_json['lang']
|
language = pysword_module_json['lang']
|
||||||
language = language[language.find('.') + 1:]
|
language = language[language.find('.') + 1:]
|
||||||
language_id = BiblesResourcesDB.get_language(language)['id']
|
language = languages.get_language(language)
|
||||||
|
if hasattr(language, 'id'):
|
||||||
|
language_id = language.id
|
||||||
self.save_meta('language_id', language_id)
|
self.save_meta('language_id', language_id)
|
||||||
books = bible.get_structure().get_books()
|
books = bible.get_structure().get_books()
|
||||||
# Count number of books
|
# Count number of books
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from lxml import etree, objectify
|
from lxml import etree
|
||||||
|
|
||||||
from openlp.core.common import translate
|
from openlp.core.common import languages, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||||
|
|
||||||
@ -62,7 +62,9 @@ class ZefaniaBible(BibleDB):
|
|||||||
language_id = None
|
language_id = None
|
||||||
language = zefania_bible_tree.xpath("/XMLBIBLE/INFORMATION/language/text()")
|
language = zefania_bible_tree.xpath("/XMLBIBLE/INFORMATION/language/text()")
|
||||||
if language:
|
if language:
|
||||||
language_id = BiblesResourcesDB.get_language(language[0])
|
language = languages.get_language(language[0])
|
||||||
|
if hasattr(language, 'id'):
|
||||||
|
language_id = language.id
|
||||||
# The language couldn't be detected, ask the user
|
# The language couldn't be detected, ask the user
|
||||||
if not language_id:
|
if not language_id:
|
||||||
language_id = self.get_language(bible_name)
|
language_id = self.get_language(bible_name)
|
||||||
|
Binary file not shown.
@ -46,7 +46,7 @@ class EasySlidesImport(SongImport):
|
|||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
log.info('Importing EasySlides XML file {source}'.format(source=self.import_source))
|
log.info('Importing EasySlides XML file {source}'.format(source=self.import_source))
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True, recover=True)
|
||||||
parsed_file = etree.parse(self.import_source, parser)
|
parsed_file = etree.parse(self.import_source, parser)
|
||||||
xml = etree.tostring(parsed_file).decode()
|
xml = etree.tostring(parsed_file).decode()
|
||||||
song_xml = objectify.fromstring(xml)
|
song_xml = objectify.fromstring(xml)
|
||||||
|
@ -73,6 +73,14 @@ class VideoPsalmImport(SongImport):
|
|||||||
processed_content += c
|
processed_content += c
|
||||||
c = next(file_content_it)
|
c = next(file_content_it)
|
||||||
processed_content += '"' + c
|
processed_content += '"' + c
|
||||||
|
# Remove control characters
|
||||||
|
elif (c < chr(32)):
|
||||||
|
processed_content += ' '
|
||||||
|
# Handle escaped characters
|
||||||
|
elif c == '\\':
|
||||||
|
processed_content += c
|
||||||
|
c = next(file_content_it)
|
||||||
|
processed_content += c
|
||||||
else:
|
else:
|
||||||
processed_content += c
|
processed_content += c
|
||||||
songbook = json.loads(processed_content.strip())
|
songbook = json.loads(processed_content.strip())
|
||||||
|
@ -458,7 +458,7 @@ class OpenLyrics(object):
|
|||||||
self._add_tag_to_formatting(tag, tags_element)
|
self._add_tag_to_formatting(tag, tags_element)
|
||||||
# Replace end tags.
|
# Replace end tags.
|
||||||
for tag in end_tags:
|
for tag in end_tags:
|
||||||
text = text.replace('{/{tag}}}'.format(tag=tag), '</tag>')
|
text = text.replace('{{{tag}}}'.format(tag=tag), '</tag>')
|
||||||
# Replace \n with <br/>.
|
# Replace \n with <br/>.
|
||||||
text = text.replace('\n', '<br/>')
|
text = text.replace('\n', '<br/>')
|
||||||
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
||||||
@ -643,7 +643,7 @@ class OpenLyrics(object):
|
|||||||
# Append text from tail and add formatting end tag.
|
# Append text from tail and add formatting end tag.
|
||||||
# TODO: Verify format() with template variables
|
# TODO: Verify format() with template variables
|
||||||
if element.tag == NSMAP % 'tag' and use_endtag:
|
if element.tag == NSMAP % 'tag' and use_endtag:
|
||||||
text += '{/{name}}}'.format(name=element.get('name'))
|
text += '{{{name}}}'.format(name=element.get('name'))
|
||||||
# Append text from tail.
|
# Append text from tail.
|
||||||
if element.tail:
|
if element.tail:
|
||||||
text += element.tail
|
text += element.tail
|
||||||
|
BIN
resources/images/bibles_search_clear.png
Normal file
BIN
resources/images/bibles_search_clear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
resources/images/bibles_search_combined.png
Normal file
BIN
resources/images/bibles_search_combined.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@ -30,9 +30,11 @@
|
|||||||
<file>image_new_group.png</file>
|
<file>image_new_group.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="bibles">
|
<qresource prefix="bibles">
|
||||||
|
<file>bibles_search_combined.png</file>
|
||||||
<file>bibles_search_text.png</file>
|
<file>bibles_search_text.png</file>
|
||||||
<file>bibles_search_reference.png</file>
|
<file>bibles_search_reference.png</file>
|
||||||
<file>bibles_upgrade_alert.png</file>
|
<file>bibles_upgrade_alert.png</file>
|
||||||
|
<file>bibles_search_clear.png</file>
|
||||||
<file>bibles_search_unlock.png</file>
|
<file>bibles_search_unlock.png</file>
|
||||||
<file>bibles_search_lock.png</file>
|
<file>bibles_search_lock.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
@ -63,9 +63,10 @@ class OpenLPJobs(object):
|
|||||||
Branch_Windows_Interface = 'Branch-04b-Windows_Interface_Tests'
|
Branch_Windows_Interface = 'Branch-04b-Windows_Interface_Tests'
|
||||||
Branch_PEP = 'Branch-05a-Code_Analysis'
|
Branch_PEP = 'Branch-05a-Code_Analysis'
|
||||||
Branch_Coverage = 'Branch-05b-Test_Coverage'
|
Branch_Coverage = 'Branch-05b-Test_Coverage'
|
||||||
|
Branch_Pylint = 'Branch-05c-Code_Analysis2'
|
||||||
|
|
||||||
Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface,
|
Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface,
|
||||||
Branch_PEP, Branch_Coverage]
|
Branch_PEP, Branch_Coverage, Branch_Pylint]
|
||||||
|
|
||||||
|
|
||||||
class Colour(object):
|
class Colour(object):
|
||||||
|
109
tests/functional/openlp_core_common/test_languages.py
Normal file
109
tests/functional/openlp_core_common/test_languages.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2016 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 #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
Package to test the openlp.core.lib.languages package.
|
||||||
|
"""
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from openlp.core.common import languages
|
||||||
|
|
||||||
|
|
||||||
|
class TestLanguages(TestCase):
|
||||||
|
|
||||||
|
def languages_type_test(self):
|
||||||
|
"""
|
||||||
|
Test the languages variable type
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: The languages module
|
||||||
|
# WHEN: Accessing the languages variable
|
||||||
|
# THEN: It should be of type list
|
||||||
|
self.assertIsInstance(languages.languages, list, 'languages.languages should be of type list')
|
||||||
|
|
||||||
|
def language_selection_languages_type_test(self):
|
||||||
|
"""
|
||||||
|
Test the selection of a language
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: A list of languages from the languages module
|
||||||
|
# WHEN: Selecting the first item
|
||||||
|
language = languages.languages[0]
|
||||||
|
|
||||||
|
# THEN: It should be an instance of the Language namedtuple
|
||||||
|
self.assertIsInstance(language, languages.Language)
|
||||||
|
self.assertEqual(language.id, 1)
|
||||||
|
self.assertEqual(language.name, '(Afan) Oromo')
|
||||||
|
self.assertEqual(language.code, 'om')
|
||||||
|
|
||||||
|
def get_language_name_test(self):
|
||||||
|
"""
|
||||||
|
Test get_language() when supplied with a language name.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: A language name, in capitals
|
||||||
|
# WHEN: Calling get_language with it
|
||||||
|
language = languages.get_language('YORUBA')
|
||||||
|
|
||||||
|
# THEN: The Language found using that name should be returned
|
||||||
|
self.assertIsInstance(language, languages.Language)
|
||||||
|
self.assertEqual(language.id, 137)
|
||||||
|
self.assertEqual(language.name, 'Yoruba')
|
||||||
|
self.assertEqual(language.code, 'yo')
|
||||||
|
|
||||||
|
def get_language_code_test(self):
|
||||||
|
"""
|
||||||
|
Test get_language() when supplied with a language code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: A language code in capitals
|
||||||
|
# WHEN: Calling get_language with it
|
||||||
|
language = languages.get_language('IA')
|
||||||
|
|
||||||
|
# THEN: The Language found using that code should be returned
|
||||||
|
self.assertIsInstance(language, languages.Language)
|
||||||
|
self.assertEqual(language.id, 51)
|
||||||
|
self.assertEqual(language.name, 'Interlingua')
|
||||||
|
self.assertEqual(language.code, 'ia')
|
||||||
|
|
||||||
|
def get_language_invalid_test(self):
|
||||||
|
"""
|
||||||
|
Test get_language() when supplied with a string which is not a valid language name or code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: A language code
|
||||||
|
# WHEN: Calling get_language with it
|
||||||
|
language = languages.get_language('qwerty')
|
||||||
|
|
||||||
|
# THEN: None should be returned
|
||||||
|
self.assertIsNone(language)
|
||||||
|
|
||||||
|
def get_language_invalid__none_test(self):
|
||||||
|
"""
|
||||||
|
Test get_language() when supplied with a string which is not a valid language name or code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: A language code
|
||||||
|
# WHEN: Calling get_language with it
|
||||||
|
language = languages.get_language(None)
|
||||||
|
|
||||||
|
# THEN: None should be returned
|
||||||
|
self.assertIsNone(language)
|
@ -22,43 +22,82 @@
|
|||||||
"""
|
"""
|
||||||
Package to test the openlp.core.lib.theme package.
|
Package to test the openlp.core.lib.theme package.
|
||||||
"""
|
"""
|
||||||
from tests.functional import MagicMock, patch
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
import os
|
||||||
|
|
||||||
from openlp.core.lib.theme import ThemeXML
|
from openlp.core.lib.theme import ThemeXML
|
||||||
|
|
||||||
|
|
||||||
class TestTheme(TestCase):
|
class TestThemeXML(TestCase):
|
||||||
"""
|
"""
|
||||||
Test the functions in the Theme module
|
Test the ThemeXML class
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
|
||||||
"""
|
|
||||||
Create the UI
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""
|
|
||||||
Delete all the C++ objects at the end so that we don't have a segfault
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_new_theme(self):
|
def test_new_theme(self):
|
||||||
"""
|
"""
|
||||||
Test the theme creation - basic test
|
Test the ThemeXML constructor
|
||||||
"""
|
"""
|
||||||
# GIVEN: A new theme
|
# GIVEN: The ThemeXML class
|
||||||
|
# WHEN: A theme object is created
|
||||||
# WHEN: A theme is created
|
|
||||||
default_theme = ThemeXML()
|
default_theme = ThemeXML()
|
||||||
|
|
||||||
# THEN: We should get some default behaviours
|
# THEN: The default values should be correct
|
||||||
self.assertTrue(default_theme.background_border_color == '#000000', 'The theme should have a black border')
|
self.assertEqual('#000000', default_theme.background_border_color,
|
||||||
self.assertTrue(default_theme.background_type == 'solid', 'The theme should have a solid backgrounds')
|
'background_border_color should be "#000000"')
|
||||||
self.assertTrue(default_theme.display_vertical_align == 0,
|
self.assertEqual('solid', default_theme.background_type, 'background_type should be "solid"')
|
||||||
'The theme should have a display_vertical_align of 0')
|
self.assertEqual(0, default_theme.display_vertical_align, 'display_vertical_align should be 0')
|
||||||
self.assertTrue(default_theme.font_footer_name == "Arial",
|
self.assertEqual('Arial', default_theme.font_footer_name, 'font_footer_name should be "Arial"')
|
||||||
'The theme should have a font_footer_name of Arial')
|
self.assertFalse(default_theme.font_main_bold, 'font_main_bold should be False')
|
||||||
self.assertTrue(default_theme.font_main_bold is False, 'The theme should have a font_main_bold of false')
|
self.assertEqual(47, len(default_theme.__dict__), 'The theme should have 47 attributes')
|
||||||
self.assertTrue(len(default_theme.__dict__) == 47, 'The theme should have 47 variables')
|
|
||||||
|
def test_expand_json(self):
|
||||||
|
"""
|
||||||
|
Test the expand_json method
|
||||||
|
"""
|
||||||
|
# GIVEN: A ThemeXML object and some JSON to "expand"
|
||||||
|
theme = ThemeXML()
|
||||||
|
theme_json = {
|
||||||
|
'background': {
|
||||||
|
'border_color': '#000000',
|
||||||
|
'type': 'solid'
|
||||||
|
},
|
||||||
|
'display': {
|
||||||
|
'vertical_align': 0
|
||||||
|
},
|
||||||
|
'font': {
|
||||||
|
'footer': {
|
||||||
|
'bold': False
|
||||||
|
},
|
||||||
|
'main': {
|
||||||
|
'name': 'Arial'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# WHEN: ThemeXML.expand_json() is run
|
||||||
|
theme.expand_json(theme_json)
|
||||||
|
|
||||||
|
# THEN: The attributes should be set on the object
|
||||||
|
self.assertEqual('#000000', theme.background_border_color, 'background_border_color should be "#000000"')
|
||||||
|
self.assertEqual('solid', theme.background_type, 'background_type should be "solid"')
|
||||||
|
self.assertEqual(0, theme.display_vertical_align, 'display_vertical_align should be 0')
|
||||||
|
self.assertFalse(theme.font_footer_bold, 'font_footer_bold should be False')
|
||||||
|
self.assertEqual('Arial', theme.font_main_name, 'font_main_name should be "Arial"')
|
||||||
|
|
||||||
|
def test_extend_image_filename(self):
|
||||||
|
"""
|
||||||
|
Test the extend_image_filename method
|
||||||
|
"""
|
||||||
|
# GIVEN: A theme object
|
||||||
|
theme = ThemeXML()
|
||||||
|
theme.theme_name = 'MyBeautifulTheme '
|
||||||
|
theme.background_filename = ' video.mp4'
|
||||||
|
theme.background_type = 'video'
|
||||||
|
path = os.path.expanduser('~')
|
||||||
|
|
||||||
|
# WHEN: ThemeXML.extend_image_filename is run
|
||||||
|
theme.extend_image_filename(path)
|
||||||
|
|
||||||
|
# THEN: The filename of the background should be correct
|
||||||
|
expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4')
|
||||||
|
self.assertEqual(expected_filename, theme.background_filename)
|
||||||
|
self.assertEqual('MyBeautifulTheme', theme.theme_name)
|
||||||
|
87
tests/functional/openlp_plugins/bibles/test_db.py
Normal file
87
tests/functional/openlp_plugins/bibles/test_db.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2016 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 db submodule of the Bibles plugin.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from openlp.plugins.bibles.lib.db import BibleDB
|
||||||
|
from tests.functional import MagicMock, patch
|
||||||
|
|
||||||
|
|
||||||
|
class TestBibleDB(TestCase):
|
||||||
|
"""
|
||||||
|
Test the functions in the BibleDB class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_get_language_canceled(self):
|
||||||
|
"""
|
||||||
|
Test the BibleDB.get_language method when the user rejects the dialog box
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked LanguageForm with an exec method which returns QtDialog.Rejected and an instance of BibleDB
|
||||||
|
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
|
||||||
|
patch('openlp.plugins.bibles.forms.LanguageForm') as mocked_language_form:
|
||||||
|
|
||||||
|
# The integer value of QtDialog.Rejected is 0. Using the enumeration causes a seg fault for some reason
|
||||||
|
mocked_language_form_instance = MagicMock(**{'exec.return_value': 0})
|
||||||
|
mocked_language_form.return_value = mocked_language_form_instance
|
||||||
|
mocked_parent = MagicMock()
|
||||||
|
instance = BibleDB(mocked_parent)
|
||||||
|
mocked_wizard = MagicMock()
|
||||||
|
instance.wizard = mocked_wizard
|
||||||
|
|
||||||
|
# WHEN: Calling get_language()
|
||||||
|
result = instance.get_language()
|
||||||
|
|
||||||
|
# THEN: get_language() should return False
|
||||||
|
mocked_language_form.assert_called_once_with(mocked_wizard)
|
||||||
|
mocked_language_form_instance.exec.assert_called_once_with(None)
|
||||||
|
self.assertFalse(result, 'get_language() should return False if the user rejects the dialog box')
|
||||||
|
|
||||||
|
def test_get_language_accepted(self):
|
||||||
|
"""
|
||||||
|
Test the BibleDB.get_language method when the user accepts the dialog box
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked LanguageForm with an exec method which returns QtDialog.Accepted an instance of BibleDB and
|
||||||
|
# a combobox with the selected item data as 10
|
||||||
|
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'), \
|
||||||
|
patch('openlp.plugins.bibles.lib.db.BibleDB.save_meta'), \
|
||||||
|
patch('openlp.plugins.bibles.forms.LanguageForm') as mocked_language_form:
|
||||||
|
|
||||||
|
# The integer value of QtDialog.Accepted is 1. Using the enumeration causes a seg fault for some reason
|
||||||
|
mocked_language_form_instance = MagicMock(**{'exec.return_value': 1,
|
||||||
|
'language_combo_box.itemData.return_value': 10})
|
||||||
|
mocked_language_form.return_value = mocked_language_form_instance
|
||||||
|
mocked_parent = MagicMock()
|
||||||
|
instance = BibleDB(mocked_parent)
|
||||||
|
mocked_wizard = MagicMock()
|
||||||
|
instance.wizard = mocked_wizard
|
||||||
|
|
||||||
|
# WHEN: Calling get_language()
|
||||||
|
result = instance.get_language('Bible Name')
|
||||||
|
|
||||||
|
# THEN: get_language() should return the id of the selected language in the combo box
|
||||||
|
mocked_language_form.assert_called_once_with(mocked_wizard)
|
||||||
|
mocked_language_form_instance.exec.assert_called_once_with('Bible Name')
|
||||||
|
self.assertEqual(result, 10, 'get_language() should return the id of the language the user has chosen when '
|
||||||
|
'they accept the dialog box')
|
@ -23,6 +23,7 @@
|
|||||||
This module contains tests for the lib submodule of the Presentations plugin.
|
This module contains tests for the lib submodule of the Presentations plugin.
|
||||||
"""
|
"""
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
from openlp.core.common import Registry
|
||||||
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
|
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
|
||||||
from tests.functional import MagicMock, patch
|
from tests.functional import MagicMock, patch
|
||||||
from tests.helpers.testmixin import TestMixin
|
from tests.helpers.testmixin import TestMixin
|
||||||
@ -41,6 +42,9 @@ class TestMediaItem(TestCase, TestMixin):
|
|||||||
patch('openlp.plugins.bibles.lib.mediaitem.BibleMediaItem.setup_item'):
|
patch('openlp.plugins.bibles.lib.mediaitem.BibleMediaItem.setup_item'):
|
||||||
self.media_item = BibleMediaItem(None, MagicMock())
|
self.media_item = BibleMediaItem(None, MagicMock())
|
||||||
self.setup_application()
|
self.setup_application()
|
||||||
|
self.mocked_main_window = MagicMock()
|
||||||
|
Registry.create()
|
||||||
|
Registry().register('main_window', self.mocked_main_window)
|
||||||
|
|
||||||
def test_display_results_no_results(self):
|
def test_display_results_no_results(self):
|
||||||
"""
|
"""
|
||||||
@ -109,3 +113,40 @@ class TestMediaItem(TestCase, TestMixin):
|
|||||||
mocked_list_view.selectAll.assert_called_once_with()
|
mocked_list_view.selectAll.assert_called_once_with()
|
||||||
self.assertEqual(self.media_item.search_results, {})
|
self.assertEqual(self.media_item.search_results, {})
|
||||||
self.assertEqual(self.media_item.second_search_results, {})
|
self.assertEqual(self.media_item.second_search_results, {})
|
||||||
|
|
||||||
|
def on_quick_search_button_general_test(self):
|
||||||
|
"""
|
||||||
|
Test that general things, which should be called on all Quick searches are called.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# GIVEN: self.application as self.app, all the required functions
|
||||||
|
Registry.create()
|
||||||
|
Registry().register('application', self.app)
|
||||||
|
self.media_item.quickSearchButton = MagicMock()
|
||||||
|
self.app.process_events = MagicMock()
|
||||||
|
self.media_item.quickVersionComboBox = MagicMock()
|
||||||
|
self.media_item.quickVersionComboBox.currentText = MagicMock()
|
||||||
|
self.media_item.quickSecondComboBox = MagicMock()
|
||||||
|
self.media_item.quickSecondComboBox.currentText = MagicMock()
|
||||||
|
self.media_item.quick_search_edit = MagicMock()
|
||||||
|
self.media_item.quick_search_edit.text = MagicMock()
|
||||||
|
self.media_item.quickLockButton = MagicMock()
|
||||||
|
self.media_item.list_view = MagicMock()
|
||||||
|
self.media_item.search_results = MagicMock()
|
||||||
|
self.media_item.display_results = MagicMock()
|
||||||
|
self.media_item.check_search_result = MagicMock()
|
||||||
|
self.app.set_normal_cursor = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: on_quick_search_button is called
|
||||||
|
self.media_item.on_quick_search_button()
|
||||||
|
|
||||||
|
# THEN: Search should had been started and finalized properly
|
||||||
|
self.assertEqual(1, self.app.process_events.call_count, 'Normal cursor should had been called once')
|
||||||
|
self.assertEqual(1, self.media_item.quickVersionComboBox.currentText.call_count, 'Should had been called once')
|
||||||
|
self.assertEqual(1, self.media_item.quickSecondComboBox.currentText.call_count, 'Should had been called once')
|
||||||
|
self.assertEqual(1, self.media_item.quick_search_edit.text.call_count, 'Text edit Should had been called once')
|
||||||
|
self.assertEqual(1, self.media_item.quickLockButton.isChecked.call_count, 'Lock Should had been called once')
|
||||||
|
self.assertEqual(1, self.media_item.display_results.call_count, 'Display results Should had been called once')
|
||||||
|
self.assertEqual(2, self.media_item.quickSearchButton.setEnabled.call_count, 'Disable and Enable the button')
|
||||||
|
self.assertEqual(1, self.media_item.check_search_result.call_count, 'Check results Should had been called once')
|
||||||
|
self.assertEqual(1, self.app.set_normal_cursor.call_count, 'Normal cursor should had been called once')
|
||||||
|
@ -70,8 +70,8 @@ class TestSwordImport(TestCase):
|
|||||||
|
|
||||||
@patch('openlp.plugins.bibles.lib.sword.SwordBible.application')
|
@patch('openlp.plugins.bibles.lib.sword.SwordBible.application')
|
||||||
@patch('openlp.plugins.bibles.lib.sword.modules')
|
@patch('openlp.plugins.bibles.lib.sword.modules')
|
||||||
@patch('openlp.plugins.bibles.lib.db.BiblesResourcesDB')
|
@patch('openlp.core.common.languages')
|
||||||
def test_simple_import(self, mocked_bible_res_db, mocked_pysword_modules, mocked_application):
|
def test_simple_import(self, mocked_languages, mocked_pysword_modules, mocked_application):
|
||||||
"""
|
"""
|
||||||
Test that a simple SWORD import works
|
Test that a simple SWORD import works
|
||||||
"""
|
"""
|
||||||
@ -88,7 +88,7 @@ class TestSwordImport(TestCase):
|
|||||||
importer.create_verse = MagicMock()
|
importer.create_verse = MagicMock()
|
||||||
importer.create_book = MagicMock()
|
importer.create_book = MagicMock()
|
||||||
importer.session = MagicMock()
|
importer.session = MagicMock()
|
||||||
mocked_bible_res_db.get_language.return_value = 'Danish'
|
mocked_languages.get_language.return_value = 'Danish'
|
||||||
mocked_bible = MagicMock()
|
mocked_bible = MagicMock()
|
||||||
mocked_genesis = MagicMock()
|
mocked_genesis = MagicMock()
|
||||||
mocked_genesis.name = 'Genesis'
|
mocked_genesis.name = 'Genesis'
|
||||||
|
@ -43,3 +43,5 @@ class TestVideoPsalmFileImport(SongImportTestHelper):
|
|||||||
"""
|
"""
|
||||||
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'),
|
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'),
|
||||||
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json')))
|
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json')))
|
||||||
|
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold2.json'),
|
||||||
|
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold2.json')))
|
||||||
|
@ -50,7 +50,8 @@ class TestBibleHTTP(TestCase):
|
|||||||
books = handler.get_books_from_http('NIV')
|
books = handler.get_books_from_http('NIV')
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(books) == 66, 'The bible should not have had any books added or removed'
|
self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
|
||||||
|
self.assertEqual(books[0], 'Genesis', 'The first bible book should be Genesis')
|
||||||
|
|
||||||
def test_bible_gateway_extract_books_support_redirect(self):
|
def test_bible_gateway_extract_books_support_redirect(self):
|
||||||
"""
|
"""
|
||||||
@ -63,7 +64,7 @@ class TestBibleHTTP(TestCase):
|
|||||||
books = handler.get_books_from_http('DN1933')
|
books = handler.get_books_from_http('DN1933')
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(books) == 66, 'This bible should have 66 books'
|
self.assertEqual(len(books), 66, 'This bible should have 66 books')
|
||||||
|
|
||||||
def test_bible_gateway_extract_verse(self):
|
def test_bible_gateway_extract_verse(self):
|
||||||
"""
|
"""
|
||||||
@ -76,7 +77,8 @@ class TestBibleHTTP(TestCase):
|
|||||||
results = handler.get_bible_chapter('NIV', 'John', 3)
|
results = handler.get_bible_chapter('NIV', 'John', 3)
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
self.assertEqual(len(results.verse_list), 36,
|
||||||
|
'The book of John should not have had any verses added or removed')
|
||||||
|
|
||||||
def test_bible_gateway_extract_verse_nkjv(self):
|
def test_bible_gateway_extract_verse_nkjv(self):
|
||||||
"""
|
"""
|
||||||
@ -89,7 +91,8 @@ class TestBibleHTTP(TestCase):
|
|||||||
results = handler.get_bible_chapter('NKJV', 'John', 3)
|
results = handler.get_bible_chapter('NKJV', 'John', 3)
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
self.assertEqual(len(results.verse_list), 36,
|
||||||
|
'The book of John should not have had any verses added or removed')
|
||||||
|
|
||||||
def test_crosswalk_extract_books(self):
|
def test_crosswalk_extract_books(self):
|
||||||
"""
|
"""
|
||||||
@ -102,7 +105,7 @@ class TestBibleHTTP(TestCase):
|
|||||||
books = handler.get_books_from_http('niv')
|
books = handler.get_books_from_http('niv')
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(books) == 66, 'The bible should not have had any books added or removed'
|
self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
|
||||||
|
|
||||||
def test_crosswalk_extract_verse(self):
|
def test_crosswalk_extract_verse(self):
|
||||||
"""
|
"""
|
||||||
@ -115,7 +118,8 @@ class TestBibleHTTP(TestCase):
|
|||||||
results = handler.get_bible_chapter('niv', 'john', 3)
|
results = handler.get_bible_chapter('niv', 'john', 3)
|
||||||
|
|
||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
self.assertEqual(len(results.verse_list), 36,
|
||||||
|
'The book of John should not have had any verses added or removed')
|
||||||
|
|
||||||
def test_bibleserver_get_bibles(self):
|
def test_bibleserver_get_bibles(self):
|
||||||
"""
|
"""
|
||||||
@ -144,9 +148,8 @@ class TestBibleHTTP(TestCase):
|
|||||||
|
|
||||||
# THEN: The list should not be None, and some known bibles should be there
|
# THEN: The list should not be None, and some known bibles should be there
|
||||||
self.assertIsNotNone(bibles)
|
self.assertIsNotNone(bibles)
|
||||||
self.assertIn(('Holman Christian Standard Bible', 'HCSB', 'en'), bibles)
|
self.assertIn(('Holman Christian Standard Bible (HCSB)', 'HCSB', 'en'), bibles)
|
||||||
|
|
||||||
@skip("Waiting for Crosswalk to fix their server")
|
|
||||||
def test_crosswalk_get_bibles(self):
|
def test_crosswalk_get_bibles(self):
|
||||||
"""
|
"""
|
||||||
Test getting list of bibles from Crosswalk.com
|
Test getting list of bibles from Crosswalk.com
|
||||||
|
35
tests/resources/videopsalmsongs/as-safe-a-stronghold2.json
Normal file
35
tests/resources/videopsalmsongs/as-safe-a-stronghold2.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"authors": [
|
||||||
|
["Martin Luther", "words"],
|
||||||
|
["Unknown", "music"]
|
||||||
|
],
|
||||||
|
"ccli_number": "12345",
|
||||||
|
"comments": "This is\nthe first comment\nThis is\nthe second comment\nThis is\nthe third comment\n",
|
||||||
|
"copyright": "Public Domain",
|
||||||
|
"song_book_name": "SongBook1",
|
||||||
|
"song_number": 0,
|
||||||
|
"title": "A Safe Stronghold Our God is Still",
|
||||||
|
"topics": [
|
||||||
|
"tema1",
|
||||||
|
"tema2"
|
||||||
|
],
|
||||||
|
"verse_order_list": [],
|
||||||
|
"verses": [
|
||||||
|
[
|
||||||
|
"As safe a stronghold our God is still,\nA trusty shield and weapon;\nHe’ll help us clear from all the ill\nThat hath us now o’ertaken.\nThe ancient prince of hell\nHath risen with purpose fell;\nStrong mail of craft and power\nHe weareth in this hour;\nOn earth is not His fellow.",
|
||||||
|
"v"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"With \"force\" of arms we nothing can,\nFull soon were we down-ridden;\nBut for us fights \\ the proper Man,\nWhom God Himself hath bidden.\nAsk ye: Who is this same?\nChrist Jesus is His name,\nThe Lord Sabaoth’s Son;\nHe, and no other one,\nShall conquer in the battle.",
|
||||||
|
"v"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"And were this world all devils o’er,\nAnd watching to devour us,\nWe lay it not to heart so sore;\nNot they can overpower us.\nAnd let the prince of ill\nLook grim as e’er he will,\nHe harms us not a whit;\nFor why? his doom is writ;\nA word shall quickly slay him.",
|
||||||
|
"v"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"God’s word, for all their craft and force,\nOne moment will not linger,\nBut, spite of hell, shall have its course;\n’Tis written by His finger.\nAnd though they take our life,\nGoods, honour, children, wife,\nYet is their profit small:\nThese things shall vanish all;\nThe city of God remaineth.",
|
||||||
|
"v"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
{Abbreviation:"SB1",Copyright:"Public domain",Songs:[{ID:3,Composer:"Unknown",Author:"Martin Luther",Copyright:"Public
|
||||||
|
Domain",Theme:"tema1
|
||||||
|
tema2",CCLI:"12345",Alias:"A safe stronghold",Memo1:"This is
|
||||||
|
the first comment
|
||||||
|
",Memo2:"This is
|
||||||
|
the second comment
|
||||||
|
",Memo3:"This is
|
||||||
|
the third comment
|
||||||
|
",Reference:"reference",Guid:"jtCkrJdPIUOmECjaQylg/g",Verses:[{
|
||||||
|
Text:"As safe a stronghold our God is still,
|
||||||
|
A trusty shield and weapon;
|
||||||
|
He’ll help us clear from all the ill
|
||||||
|
That hath us now o’ertaken.
|
||||||
|
The ancient prince of hell
|
||||||
|
Hath risen with purpose fell;
|
||||||
|
Strong mail of craft and power
|
||||||
|
He weareth in this hour;
|
||||||
|
On earth is not His fellow."},{ID:2,
|
||||||
|
Text:"With \"force\" of arms we nothing can,
|
||||||
|
Full soon were we down-ridden;
|
||||||
|
But for us fights \\ the proper Man,
|
||||||
|
Whom God Himself hath bidden.
|
||||||
|
Ask ye: Who is this same?
|
||||||
|
Christ Jesus is His name,
|
||||||
|
The Lord Sabaoth’s Son;
|
||||||
|
He, and no other one,
|
||||||
|
Shall conquer in the battle."},{ID:3,
|
||||||
|
Text:"And were this world all devils o’er,
|
||||||
|
And watching to devour us,
|
||||||
|
We lay it not to heart so sore;
|
||||||
|
Not they can overpower us.
|
||||||
|
And let the prince of ill
|
||||||
|
Look grim as e’er he will,
|
||||||
|
He harms us not a whit;
|
||||||
|
For why? his doom is writ;
|
||||||
|
A word shall quickly slay him."},{ID:4,
|
||||||
|
Text:"God’s word, for all their craft and force,
|
||||||
|
One moment will not linger,
|
||||||
|
But, spite of hell, shall have its course;
|
||||||
|
’Tis written by His finger.
|
||||||
|
And though they take our life,
|
||||||
|
Goods, honour, children, wife,
|
||||||
|
Yet is their profit small:
|
||||||
|
These things shall vanish all;
|
||||||
|
The city of God remaineth."}],AudioFile:"282.mp3",IsAudioFileEnabled:1,
|
||||||
|
Text:"A Safe Stronghold Our God is Still"}],Guid:"khiHU2blX0Kb41dGdbDLhA",VersionDate:"20121012000000",
|
||||||
|
Text:"SongBook1"}
|
@ -23,8 +23,8 @@
|
|||||||
Package to test for proper bzr tags.
|
Package to test for proper bzr tags.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import logging
|
|
||||||
import platform
|
import platform
|
||||||
|
import sys
|
||||||
from unittest import TestCase, SkipTest
|
from unittest import TestCase, SkipTest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -46,9 +46,18 @@ class TestPylint(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test for pylint errors
|
Test for pylint errors
|
||||||
"""
|
"""
|
||||||
|
# Test if this file is specified in the arguments, if not skip the test.
|
||||||
|
in_argv = False
|
||||||
|
for arg in sys.argv:
|
||||||
|
if arg.endswith('test_pylint.py') or arg.endswith('test_pylint'):
|
||||||
|
in_argv = True
|
||||||
|
break
|
||||||
|
if not in_argv:
|
||||||
|
raise SkipTest('test_pylint.py not specified in arguments - skipping tests using pylint.')
|
||||||
|
|
||||||
# GIVEN: Some checks to disable and enable, and the pylint script
|
# GIVEN: Some checks to disable and enable, and the pylint script
|
||||||
disabled_checks = 'import-error,no-member'
|
disabled_checks = 'import-error,no-member'
|
||||||
enabled_checks = 'missing-format-argument-key,unused-format-string-argument'
|
enabled_checks = 'missing-format-argument-key,unused-format-string-argument,bad-format-string'
|
||||||
if is_win() or 'arch' in platform.dist()[0].lower():
|
if is_win() or 'arch' in platform.dist()[0].lower():
|
||||||
pylint_script = 'pylint'
|
pylint_script = 'pylint'
|
||||||
else:
|
else:
|
||||||
@ -84,6 +93,9 @@ class TestPylint(TestCase):
|
|||||||
# Filter out PyQt related errors
|
# Filter out PyQt related errors
|
||||||
elif ('no-name-in-module' in line or 'no-member' in line) and 'PyQt5' in line:
|
elif ('no-name-in-module' in line or 'no-member' in line) and 'PyQt5' in line:
|
||||||
continue
|
continue
|
||||||
|
# Filter out distutils related errors
|
||||||
|
elif 'distutils' in line:
|
||||||
|
continue
|
||||||
elif self._is_line_tolerated(line):
|
elif self._is_line_tolerated(line):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user