Merge lp:~raoul-snyman/openlp/fix-translations-2.4 into lp:openlp/2.4

Proposed by Raoul Snyman
Status: Merged
Merged at revision: 2679
Proposed branch: lp:~raoul-snyman/openlp/fix-translations-2.4
Merge into: lp:openlp/2.4
Diff against target: 262 lines (+146/-16)
5 files modified
CHANGELOG.rst (+1/-0)
openlp/core/__init__.py (+6/-7)
openlp/core/utils/languagemanager.py (+5/-3)
openlp/plugins/songs/forms/songmaintenanceform.py (+4/-5)
tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py (+130/-1)
To merge this branch: bzr merge lp:~raoul-snyman/openlp/fix-translations-2.4
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Tomas Groth Approve
Review via email: mp+321131@code.launchpad.net

This proposal supersedes a proposal from 2017-03-28.

Commit message

Fix a problem with loading Qt's translation files, bug #1676163

To post a comment you must log in.
Revision history for this message
Tomas Groth (tomasgroth) :
review: Approve
Revision history for this message
Tim Bentley (trb143) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGELOG.rst'
2--- CHANGELOG.rst 2017-03-22 06:21:02 +0000
3+++ CHANGELOG.rst 2017-03-28 00:33:42 +0000
4@@ -8,3 +8,4 @@
5 * Fix opening the data folder (KDE thought the old way was an SMB share)
6 * Fix a problem with the new QMediaPlayer not controlling the playlist anymore
7 * Added importing of author types to the OpenLP 2 song importer
8+* Fix a problem with loading Qt's translation files, bug #1676163
9
10=== modified file 'openlp/core/__init__.py'
11--- openlp/core/__init__.py 2017-03-01 18:24:27 +0000
12+++ openlp/core/__init__.py 2017-03-28 00:33:42 +0000
13@@ -426,13 +426,12 @@
14 sys.exit()
15 # i18n Set Language
16 language = LanguageManager.get_language()
17- application_translator, default_translator = LanguageManager.get_translator(language)
18- if not application_translator.isEmpty():
19- application.installTranslator(application_translator)
20- if not default_translator.isEmpty():
21- application.installTranslator(default_translator)
22- else:
23- log.debug('Could not find default_translator.')
24+ translators = LanguageManager.get_translator(language)
25+ for translator in translators:
26+ if not translator.isEmpty():
27+ application.installTranslator(translator)
28+ if not translators:
29+ log.debug('Could not find translators.')
30 if args and not args.no_error_form:
31 sys.excepthook = application.hook_exception
32 sys.exit(application.run(qt_args))
33
34=== modified file 'openlp/core/utils/languagemanager.py'
35--- openlp/core/utils/languagemanager.py 2016-12-31 11:05:48 +0000
36+++ openlp/core/utils/languagemanager.py 2017-03-28 00:33:42 +0000
37@@ -24,7 +24,6 @@
38 """
39 import logging
40 import re
41-import sys
42
43 from PyQt5 import QtCore, QtWidgets
44
45@@ -56,9 +55,12 @@
46 # A translator for buttons and other default strings provided by Qt.
47 if not is_win() and not is_macosx():
48 lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
49+ # As of Qt5, the core translations come in 2 files per language
50 default_translator = QtCore.QTranslator()
51 default_translator.load('qt_%s' % language, lang_path)
52- return app_translator, default_translator
53+ base_translator = QtCore.QTranslator()
54+ base_translator.load('qtbase_%s' % language, lang_path)
55+ return app_translator, default_translator, base_translator
56
57 @staticmethod
58 def find_qm_files():
59@@ -69,7 +71,7 @@
60 trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
61 file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name)
62 # Remove qm files from the list which start with "qt_".
63- file_names = [file_ for file_ in file_names if not file_.startswith('qt_')]
64+ file_names = [file_ for file_ in file_names if not file_.startswith('qt_') or file_.startswith('qtbase_')]
65 return list(map(trans_dir.filePath, file_names))
66
67 @staticmethod
68
69=== modified file 'openlp/plugins/songs/forms/songmaintenanceform.py'
70--- openlp/plugins/songs/forms/songmaintenanceform.py 2016-12-31 11:05:48 +0000
71+++ openlp/plugins/songs/forms/songmaintenanceform.py 2017-03-28 00:33:42 +0000
72@@ -20,7 +20,6 @@
73 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
74 ###############################################################################
75 import logging
76-import os
77
78 from PyQt5 import QtCore, QtWidgets
79 from sqlalchemy.sql import and_
80@@ -167,7 +166,7 @@
81 Author.display_name == new_author.display_name
82 )
83 )
84- return self.__check_object_exists(authors, new_author, edit)
85+ return self._check_object_exists(authors, new_author, edit)
86
87 def check_topic_exists(self, new_topic, edit=False):
88 """
89@@ -177,7 +176,7 @@
90 :param edit: Are we editing the song?
91 """
92 topics = self.manager.get_all_objects(Topic, Topic.name == new_topic.name)
93- return self.__check_object_exists(topics, new_topic, edit)
94+ return self._check_object_exists(topics, new_topic, edit)
95
96 def check_song_book_exists(self, new_book, edit=False):
97 """
98@@ -188,9 +187,9 @@
99 """
100 books = self.manager.get_all_objects(
101 Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher))
102- return self.__check_object_exists(books, new_book, edit)
103+ return self._check_object_exists(books, new_book, edit)
104
105- def __check_object_exists(self, existing_objects, new_object, edit):
106+ def _check_object_exists(self, existing_objects, new_object, edit):
107 """
108 Utility method to check for an existing object.
109
110
111=== modified file 'tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py'
112--- tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py 2017-03-22 06:13:12 +0000
113+++ tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py 2017-03-28 00:33:42 +0000
114@@ -25,7 +25,7 @@
115 from unittest import TestCase
116 from unittest.mock import MagicMock, patch, call
117
118-from PyQt5 import QtCore, QtTest, QtWidgets
119+from PyQt5 import QtCore, QtWidgets
120
121 from openlp.core.common import Registry, UiStrings
122 from openlp.plugins.songs.forms.songmaintenanceform import SongMaintenanceForm
123@@ -89,6 +89,7 @@
124 mocked_reset_song_books.assert_called_once_with()
125 mocked_type_list_widget.setFocus.assert_called_once_with()
126 mocked_exec.assert_called_once_with(self.form)
127+ assert result is True
128
129 def test_get_current_item_id_no_item(self):
130 """
131@@ -291,3 +292,131 @@
132 MockedQListWidgetItem.assert_called_once_with('Hymnal (Hymns and Psalms, Inc.)')
133 mocked_song_book_item.setData.assert_called_once_with(QtCore.Qt.UserRole, 1)
134 mocked_song_book_list_widget.addItem.assert_called_once_with(mocked_song_book_item)
135+
136+ @patch('openlp.plugins.songs.forms.songmaintenanceform.and_')
137+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Author')
138+ def test_check_author_exists(self, MockedAuthor, mocked_and):
139+ """
140+ Test the check_author_exists() method
141+ """
142+ # GIVEN: A bunch of mocked out stuff
143+ MockedAuthor.first_name = 'John'
144+ MockedAuthor.last_name = 'Newton'
145+ MockedAuthor.display_name = 'John Newton'
146+ mocked_new_author = MagicMock()
147+ mocked_new_author.first_name = 'John'
148+ mocked_new_author.last_name = 'Newton'
149+ mocked_new_author.display_name = 'John Newton'
150+ mocked_and.return_value = True
151+ mocked_authors = [MagicMock(), MagicMock()]
152+ self.mocked_manager.get_all_objects.return_value = mocked_authors
153+
154+ # WHEN: check_author_exists() is called
155+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
156+ mocked_check_object_exists.return_value = True
157+ result = self.form.check_author_exists(mocked_new_author, edit=True)
158+
159+ # THEN: The correct result is returned
160+ mocked_and.assert_called_once_with(True, True, True)
161+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedAuthor, True)
162+ mocked_check_object_exists.assert_called_once_with(mocked_authors, mocked_new_author, True)
163+ assert result is True
164+
165+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Topic')
166+ def test_check_topic_exists(self, MockedTopic):
167+ """
168+ Test the check_topic_exists() method
169+ """
170+ # GIVEN: Some mocked stuff
171+ MockedTopic.name = 'Grace'
172+ mocked_new_topic = MagicMock()
173+ mocked_new_topic.name = 'Grace'
174+ mocked_topics = [MagicMock(), MagicMock()]
175+ self.mocked_manager.get_all_objects.return_value = mocked_topics
176+
177+ # WHEN: check_topic_exists() is run
178+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
179+ mocked_check_object_exists.return_value = True
180+ result = self.form.check_topic_exists(mocked_new_topic, True)
181+
182+ # THEN: The correct things should have been called
183+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedTopic, True)
184+ mocked_check_object_exists.assert_called_once_with(mocked_topics, mocked_new_topic, True)
185+ assert result is True
186+
187+ @patch('openlp.plugins.songs.forms.songmaintenanceform.and_')
188+ @patch('openlp.plugins.songs.forms.songmaintenanceform.Book')
189+ def test_check_song_book_exists(self, MockedBook, mocked_and):
190+ """
191+ Test the check_song_book_exists() method
192+ """
193+ # GIVEN: Some mocked stuff
194+ MockedBook.name = 'Hymns'
195+ MockedBook.publisher = 'Christian Songs'
196+ mocked_new_book = MagicMock()
197+ mocked_new_book.name = 'Hymns'
198+ mocked_new_book.publisher = 'Christian Songs'
199+ mocked_and.return_value = True
200+ mocked_books = [MagicMock(), MagicMock()]
201+ self.mocked_manager.get_all_objects.return_value = mocked_books
202+
203+ # WHEN: check_book_exists() is run
204+ with patch.object(self.form, '_check_object_exists') as mocked_check_object_exists:
205+ mocked_check_object_exists.return_value = True
206+ result = self.form.check_song_book_exists(mocked_new_book, True)
207+
208+ # THEN: The correct things should have been called
209+ mocked_and.assert_called_once_with(True, True)
210+ self.mocked_manager.get_all_objects.assert_called_once_with(MockedBook, True)
211+ mocked_check_object_exists.assert_called_once_with(mocked_books, mocked_new_book, True)
212+ assert result is True
213+
214+ def test_check_object_exists_no_existing_objects(self):
215+ """
216+ Test the _check_object_exists() method when there are no existing objects
217+ """
218+ # GIVEN: A SongMaintenanceForm instance
219+ # WHEN: _check_object_exists() is called without existing objects
220+ result = self.form._check_object_exists([], None, False)
221+
222+ # THEN: The result should be True
223+ assert result is True
224+
225+ def test_check_object_exists_without_edit(self):
226+ """
227+ Test the _check_object_exists() method when edit is false
228+ """
229+ # GIVEN: A SongMaintenanceForm instance
230+ # WHEN: _check_object_exists() is called with edit set to false
231+ result = self.form._check_object_exists([MagicMock()], None, False)
232+
233+ # THEN: The result should be False
234+ assert result is False
235+
236+ def test_check_object_exists_not_found(self):
237+ """
238+ Test the _check_object_exists() method when the object is not found
239+ """
240+ # GIVEN: A SongMaintenanceForm instance and some mocked objects
241+ mocked_existing_objects = [MagicMock(id=1)]
242+ mocked_new_object = MagicMock(id=2)
243+
244+ # WHEN: _check_object_exists() is called with edit set to false
245+ result = self.form._check_object_exists(mocked_existing_objects, mocked_new_object, True)
246+
247+ # THEN: The result should be False
248+ assert result is False
249+
250+ def test_check_object_exists(self):
251+ """
252+ Test the _check_object_exists() method
253+ """
254+ # GIVEN: A SongMaintenanceForm instance and some mocked objects
255+ mocked_existing_objects = [MagicMock(id=1)]
256+ mocked_new_object = MagicMock(id=1)
257+
258+ # WHEN: _check_object_exists() is called with edit set to false
259+ result = self.form._check_object_exists(mocked_existing_objects, mocked_new_object, True)
260+
261+ # THEN: The result should be False
262+ assert result is True

Subscribers

People subscribed via source and target branches

to all changes: