openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #31335
[Merge] lp:~raoul-snyman/openlp/fix-translations-2.4 into lp:openlp/2.4
Raoul Snyman has proposed merging lp:~raoul-snyman/openlp/fix-translations-2.4 into lp:openlp/2.4.
Commit message:
Fix a problem with loading Qt's translation files, bug #1676163
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
Bug #1676163 in OpenLP: "Missing Qt 5 translations (OLP 2.3 >)"
https://bugs.launchpad.net/openlp/+bug/1676163
For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/fix-translations-2.4/+merge/321131
Fix a problem with loading Qt's translation files
Add this to your merge proposal:
--------------------------------
lp:~raoul-snyman/openlp/fix-translations-2.4 (revision 2680)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1943/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1854/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1795/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1521/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/1111/
[SUCCESS] https://ci.openlp.io/job/Branch-05a-Code_Analysis/1179/
[SUCCESS] https://ci.openlp.io/job/Branch-05b-Test_Coverage/1047/
--
Your team OpenLP Core is requested to review the proposed merge of lp:~raoul-snyman/openlp/fix-translations-2.4 into lp:openlp/2.4.
=== modified file 'CHANGELOG.rst'
--- CHANGELOG.rst 2017-03-22 06:21:02 +0000
+++ CHANGELOG.rst 2017-03-28 00:33:42 +0000
@@ -8,3 +8,4 @@
* Fix opening the data folder (KDE thought the old way was an SMB share)
* Fix a problem with the new QMediaPlayer not controlling the playlist anymore
* Added importing of author types to the OpenLP 2 song importer
+* Fix a problem with loading Qt's translation files, bug #1676163
=== modified file 'openlp/core/__init__.py'
--- openlp/core/__init__.py 2017-03-01 18:24:27 +0000
+++ openlp/core/__init__.py 2017-03-28 00:33:42 +0000
@@ -426,13 +426,12 @@
sys.exit()
# i18n Set Language
language = LanguageManager.get_language()
- application_translator, default_translator = LanguageManager.get_translator(language)
- if not application_translator.isEmpty():
- application.installTranslator(application_translator)
- if not default_translator.isEmpty():
- application.installTranslator(default_translator)
- else:
- log.debug('Could not find default_translator.')
+ translators = LanguageManager.get_translator(language)
+ for translator in translators:
+ if not translator.isEmpty():
+ application.installTranslator(translator)
+ if not translators:
+ log.debug('Could not find translators.')
if args and not args.no_error_form:
sys.excepthook = application.hook_exception
sys.exit(application.run(qt_args))
=== modified file 'openlp/core/utils/languagemanager.py'
--- openlp/core/utils/languagemanager.py 2016-12-31 11:05:48 +0000
+++ openlp/core/utils/languagemanager.py 2017-03-28 00:33:42 +0000
@@ -24,7 +24,6 @@
"""
import logging
import re
-import sys
from PyQt5 import QtCore, QtWidgets
@@ -56,9 +55,12 @@
# A translator for buttons and other default strings provided by Qt.
if not is_win() and not is_macosx():
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
+ # As of Qt5, the core translations come in 2 files per language
default_translator = QtCore.QTranslator()
default_translator.load('qt_%s' % language, lang_path)
- return app_translator, default_translator
+ base_translator = QtCore.QTranslator()
+ base_translator.load('qtbase_%s' % language, lang_path)
+ return app_translator, default_translator, base_translator
@staticmethod
def find_qm_files():
@@ -69,7 +71,7 @@
trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name)
# Remove qm files from the list which start with "qt_".
- file_names = [file_ for file_ in file_names if not file_.startswith('qt_')]
+ file_names = [file_ for file_ in file_names if not file_.startswith('qt_') or file_.startswith('qtbase_')]
return list(map(trans_dir.filePath, file_names))
@staticmethod
=== modified file 'openlp/plugins/songs/forms/songmaintenanceform.py'
--- openlp/plugins/songs/forms/songmaintenanceform.py 2016-12-31 11:05:48 +0000
+++ openlp/plugins/songs/forms/songmaintenanceform.py 2017-03-28 00:33:42 +0000
@@ -20,7 +20,6 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
-import os
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_
@@ -167,7 +166,7 @@
Author.display_name == new_author.display_name
)
)
- return self.__check_object_exists(authors, new_author, edit)
+ return self._check_object_exists(authors, new_author, edit)
def check_topic_exists(self, new_topic, edit=False):
"""
@@ -177,7 +176,7 @@
:param edit: Are we editing the song?
"""
topics = self.manager.get_all_objects(Topic, Topic.name == new_topic.name)
- return self.__check_object_exists(topics, new_topic, edit)
+ return self._check_object_exists(topics, new_topic, edit)
def check_song_book_exists(self, new_book, edit=False):
"""
@@ -188,9 +187,9 @@
"""
books = self.manager.get_all_objects(
Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher))
- return self.__check_object_exists(books, new_book, edit)
+ return self._check_object_exists(books, new_book, edit)
- def __check_object_exists(self, existing_objects, new_object, edit):
+ def _check_object_exists(self, existing_objects, new_object, edit):
"""
Utility method to check for an existing object.
=== modified file 'tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py'
--- tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py 2017-03-22 06:13:12 +0000
+++ tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py 2017-03-28 00:33:42 +0000
@@ -25,7 +25,7 @@
from unittest import TestCase
from unittest.mock import MagicMock, patch, call
-from PyQt5 import QtCore, QtTest, QtWidgets
+from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, UiStrings
from openlp.plugins.songs.forms.songmaintenanceform import SongMaintenanceForm
@@ -89,6 +89,7 @@
mocked_reset_song_books.assert_called_once_with()
mocked_type_list_widget.setFocus.assert_called_once_with()
mocked_exec.assert_called_once_with(self.form)
+ assert result is True
def test_get_current_item_id_no_item(self):
"""
@@ -291,3 +292,131 @@
MockedQListWidgetItem.assert_called_once_with('Hymnal (Hymns and Psalms, Inc.)')
mocked_song_book_item.setData.assert_called_once_with(QtCore.Qt.UserRole, 1)
mocked_song_book_list_widget.addItem.assert_called_once_with(mocked_song_book_item)
+
+ @patch('openlp.plugins.songs.forms.songmaintenanceform.and_')
+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Author')
+ def test_check_author_exists(self, MockedAuthor, mocked_and):
+ """
+ Test the check_author_exists() method
+ """
+ # GIVEN: A bunch of mocked out stuff
+ MockedAuthor.first_name = 'John'
+ MockedAuthor.last_name = 'Newton'
+ MockedAuthor.display_name = 'John Newton'
+ mocked_new_author = MagicMock()
+ mocked_new_author.first_name = 'John'
+ mocked_new_author.last_name = 'Newton'
+ mocked_new_author.display_name = 'John Newton'
+ mocked_and.return_value = True
+ mocked_authors = [MagicMock(), MagicMock()]
+ self.mocked_manager.get_all_objects.return_value = mocked_authors
+
+ # WHEN: check_author_exists() is called
+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
+ mocked_check_object_exists.return_value = True
+ result = self.form.check_author_exists(mocked_new_author, edit=True)
+
+ # THEN: The correct result is returned
+ mocked_and.assert_called_once_with(True, True, True)
+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedAuthor, True)
+ mocked_check_object_exists.assert_called_once_with(mocked_authors, mocked_new_author, True)
+ assert result is True
+
+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Topic')
+ def test_check_topic_exists(self, MockedTopic):
+ """
+ Test the check_topic_exists() method
+ """
+ # GIVEN: Some mocked stuff
+ MockedTopic.name = 'Grace'
+ mocked_new_topic = MagicMock()
+ mocked_new_topic.name = 'Grace'
+ mocked_topics = [MagicMock(), MagicMock()]
+ self.mocked_manager.get_all_objects.return_value = mocked_topics
+
+ # WHEN: check_topic_exists() is run
+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
+ mocked_check_object_exists.return_value = True
+ result = self.form.check_topic_exists(mocked_new_topic, True)
+
+ # THEN: The correct things should have been called
+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedTopic, True)
+ mocked_check_object_exists.assert_called_once_with(mocked_topics, mocked_new_topic, True)
+ assert result is True
+
+ @patch('openlp.plugins.songs.forms.songmaintenanceform.and_')
+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Book')
+ def test_check_song_book_exists(self, MockedBook, mocked_and):
+ """
+ Test the check_song_book_exists() method
+ """
+ # GIVEN: Some mocked stuff
+ MockedBook.name = 'Hymns'
+ MockedBook.publisher = 'Christian Songs'
+ mocked_new_book = MagicMock()
+ mocked_new_book.name = 'Hymns'
+ mocked_new_book.publisher = 'Christian Songs'
+ mocked_and.return_value = True
+ mocked_books = [MagicMock(), MagicMock()]
+ self.mocked_manager.get_all_objects.return_value = mocked_books
+
+ # WHEN: check_book_exists() is run
+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
+ mocked_check_object_exists.return_value = True
+ result = self.form.check_song_book_exists(mocked_new_book, True)
+
+ # THEN: The correct things should have been called
+ mocked_and.assert_called_once_with(True, True)
+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedBook, True)
+ mocked_check_object_exists.assert_called_once_with(mocked_books, mocked_new_book, True)
+ assert result is True
+
+ def test_check_object_exists_no_existing_objects(self):
+ """
+ Test the _check_object_exists() method when there are no existing objects
+ """
+ # GIVEN: A SongMaintenanceForm instance
+ # WHEN: _check_object_exists() is called without existing objects
+ result = self.form._check_object_exists([], None, False)
+
+ # THEN: The result should be True
+ assert result is True
+
+ def test_check_object_exists_without_edit(self):
+ """
+ Test the _check_object_exists() method when edit is false
+ """
+ # GIVEN: A SongMaintenanceForm instance
+ # WHEN: _check_object_exists() is called with edit set to false
+ result = self.form._check_object_exists([MagicMock()], None, False)
+
+ # THEN: The result should be False
+ assert result is False
+
+ def test_check_object_exists_not_found(self):
+ """
+ Test the _check_object_exists() method when the object is not found
+ """
+ # GIVEN: A SongMaintenanceForm instance and some mocked objects
+ mocked_existing_objects = [MagicMock(id=1)]
+ mocked_new_object = MagicMock(id=2)
+
+ # WHEN: _check_object_exists() is called with edit set to false
+ result = self.form._check_object_exists(mocked_existing_objects, mocked_new_object, True)
+
+ # THEN: The result should be False
+ assert result is False
+
+ def test_check_object_exists(self):
+ """
+ Test the _check_object_exists() method
+ """
+ # GIVEN: A SongMaintenanceForm instance and some mocked objects
+ mocked_existing_objects = [MagicMock(id=1)]
+ mocked_new_object = MagicMock(id=1)
+
+ # WHEN: _check_object_exists() is called with edit set to false
+ result = self.form._check_object_exists(mocked_existing_objects, mocked_new_object, True)
+
+ # THEN: The result should be False
+ assert result is True
Follow ups