This commit is contained in:
Tim Bentley 2013-05-21 19:14:45 +01:00
commit e616d976f5
10 changed files with 83 additions and 34 deletions

View File

@ -30,6 +30,7 @@
The :mod:`lib` module contains most of the components and libraries that make The :mod:`lib` module contains most of the components and libraries that make
OpenLP work. OpenLP work.
""" """
from __future__ import division
from distutils.version import LooseVersion from distutils.version import LooseVersion
import logging import logging
import os import os
@ -202,12 +203,13 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
States if an icon should be build and returned from the thumb. Defaults to ``True``. States if an icon should be build and returned from the thumb. Defaults to ``True``.
``size`` ``size``
Allows to state a own size to use. Defaults to ``None``, which means that a default height of 88 is used. Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means that a default height of 88
is used.
""" """
ext = os.path.splitext(thumb_path)[1].lower() ext = os.path.splitext(thumb_path)[1].lower()
reader = QtGui.QImageReader(image_path) reader = QtGui.QImageReader(image_path)
if size is None: if size is None:
ratio = float(reader.size().width()) / float(reader.size().height()) ratio = reader.size().width() / reader.size().height()
reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88)) reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
else: else:
reader.setScaledSize(size) reader.setScaledSize(size)
@ -260,8 +262,8 @@ def resize_image(image_path, width, height, background=u'#000000'):
log.debug(u'resize_image - start') log.debug(u'resize_image - start')
reader = QtGui.QImageReader(image_path) reader = QtGui.QImageReader(image_path)
# The image's ratio. # The image's ratio.
image_ratio = float(reader.size().width()) / float(reader.size().height()) image_ratio = reader.size().width() / reader.size().height()
resize_ratio = float(width) / float(height) resize_ratio = width / height
# Figure out the size we want to resize the image to (keep aspect ratio). # Figure out the size we want to resize the image to (keep aspect ratio).
if image_ratio == resize_ratio: if image_ratio == resize_ratio:
size = QtCore.QSize(width, height) size = QtCore.QSize(width, height)
@ -282,7 +284,7 @@ def resize_image(image_path, width, height, background=u'#000000'):
new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
painter = QtGui.QPainter(new_image) painter = QtGui.QPainter(new_image)
painter.fillRect(new_image.rect(), QtGui.QColor(background)) painter.fillRect(new_image.rect(), QtGui.QColor(background))
painter.drawImage((width - real_width) / 2, (height - real_height) / 2, preview) painter.drawImage((width - real_width) // 2, (height - real_height) // 2, preview)
return new_image return new_image

View File

@ -30,6 +30,7 @@
""" """
Provide additional functionality required by OpenLP from the inherited QDockWidget. Provide additional functionality required by OpenLP from the inherited QDockWidget.
""" """
from __future__ import division
import logging import logging
from PyQt4 import QtGui from PyQt4 import QtGui
@ -55,7 +56,7 @@ class OpenLPDockWidget(QtGui.QDockWidget):
self.setWindowIcon(build_icon(icon)) self.setWindowIcon(build_icon(icon))
# Sort out the minimum width. # Sort out the minimum width.
screens = ScreenList() screens = ScreenList()
main_window_docbars = screens.current[u'size'].width() / 5 main_window_docbars = screens.current[u'size'].width() // 5
if main_window_docbars > 300: if main_window_docbars > 300:
self.setMinimumWidth(300) self.setMinimumWidth(300)
else: else:

View File

@ -26,7 +26,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from __future__ import division
import logging import logging
from PyQt4 import QtWebKit from PyQt4 import QtWebKit
@ -276,7 +276,7 @@ def build_background_css(item, width):
``item`` ``item``
Service Item containing theme and location information Service Item containing theme and location information
""" """
width = int(width) / 2 width = int(width) // 2
theme = item.themedata theme = item.themedata
background = u'background-color: black' background = u'background-color: black'
if theme: if theme:

View File

@ -26,7 +26,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from __future__ import division
import logging import logging
from PyQt4 import QtGui, QtCore, QtWebKit from PyQt4 import QtGui, QtCore, QtWebKit
@ -327,7 +327,7 @@ class Renderer(object):
screen_size = self.screens.current[u'size'] screen_size = self.screens.current[u'size']
self.width = screen_size.width() self.width = screen_size.width()
self.height = screen_size.height() self.height = screen_size.height()
self.screen_ratio = float(self.height) / float(self.width) self.screen_ratio = self.height / self.width
log.debug(u'_calculate default %s, %f' % (screen_size, self.screen_ratio)) log.debug(u'_calculate default %s, %f' % (screen_size, self.screen_ratio))
# 90% is start of footer # 90% is start of footer
self.footer_start = int(self.height * 0.90) self.footer_start = int(self.height * 0.90)
@ -546,15 +546,15 @@ class Renderer(object):
""" """
smallest_index = 0 smallest_index = 0
highest_index = len(html_list) - 1 highest_index = len(html_list) - 1
index = int(highest_index / 2) index = highest_index // 2
while True: while True:
if not self._text_fits_on_slide(previous_html + separator.join(html_list[:index + 1]).strip()): if not self._text_fits_on_slide(previous_html + separator.join(html_list[:index + 1]).strip()):
# We know that it does not fit, so change/calculate the new index and highest_index accordingly. # We know that it does not fit, so change/calculate the new index and highest_index accordingly.
highest_index = index highest_index = index
index = int(index - (index - smallest_index) / 2) index = index - (index - smallest_index) // 2
else: else:
smallest_index = index smallest_index = index
index = int(index + (highest_index - index) / 2) index = index + (highest_index - index) // 2
# We found the number of words which will fit. # We found the number of words which will fit.
if smallest_index == index or highest_index == index: if smallest_index == index or highest_index == index:
index = smallest_index index = smallest_index
@ -582,7 +582,7 @@ class Renderer(object):
html_list[0] = html_tags + html_list[0] html_list[0] = html_tags + html_list[0]
smallest_index = 0 smallest_index = 0
highest_index = len(html_list) - 1 highest_index = len(html_list) - 1
index = int(highest_index / 2) index = highest_index // 2
return previous_html, previous_raw return previous_html, previous_raw
def _text_fits_on_slide(self, text): def _text_fits_on_slide(self, text):

View File

@ -30,6 +30,7 @@
The :mod:`screen` module provides management functionality for a machines' The :mod:`screen` module provides management functionality for a machines'
displays. displays.
""" """
from __future__ import division
import logging import logging
import copy import copy
@ -232,8 +233,8 @@ class ScreenList(object):
``window`` ``window``
A QWidget we are finding the location of. A QWidget we are finding the location of.
""" """
x = window.x() + (window.width() / 2) x = window.x() + (window.width() // 2)
y = window.y() + (window.height() / 2) y = window.y() + (window.height() // 2)
for screen in self.screen_list: for screen in self.screen_list:
size = screen[u'size'] size = screen[u'size']
if x >= size.x() and x <= (size.x() + size.width()) and y >= size.y() and y <= (size.y() + size.height()): if x >= size.x() and x <= (size.x() + size.width()) and y >= size.y() and y <= (size.y() + size.height()):

View File

@ -26,7 +26,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from __future__ import division
import logging import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -85,10 +85,10 @@ class SearchEdit(QtGui.QLineEdit):
size = self.clear_button.size() size = self.clear_button.size()
frame_width = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth) frame_width = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
self.clear_button.move(self.rect().right() - frame_width - size.width(), self.clear_button.move(self.rect().right() - frame_width - size.width(),
(self.rect().bottom() + 1 - size.height()) / 2) (self.rect().bottom() + 1 - size.height()) // 2)
if hasattr(self, u'menu_button'): if hasattr(self, u'menu_button'):
size = self.menu_button.size() size = self.menu_button.size()
self.menu_button.move(self.rect().left() + frame_width + 2, (self.rect().bottom() + 1 - size.height()) / 2) self.menu_button.move(self.rect().left() + frame_width + 2, (self.rect().bottom() + 1 - size.height()) // 2)
def current_search_type(self): def current_search_type(self):
""" """

View File

@ -30,6 +30,7 @@
The :mod:`~openlp.core.lib.settingstab` module contains the base SettingsTab class which plugins use for adding their The :mod:`~openlp.core.lib.settingstab` module contains the base SettingsTab class which plugins use for adding their
own tab to the settings dialog. own tab to the settings dialog.
""" """
from __future__ import division
from PyQt4 import QtGui from PyQt4 import QtGui
@ -90,7 +91,7 @@ class SettingsTab(QtGui.QWidget):
QtGui.QWidget.resizeEvent(self, event) QtGui.QWidget.resizeEvent(self, event)
width = self.width() - self.tab_layout.spacing() - \ width = self.width() - self.tab_layout.spacing() - \
self.tab_layout.contentsMargins().left() - self.tab_layout.contentsMargins().right() self.tab_layout.contentsMargins().left() - self.tab_layout.contentsMargins().right()
left_width = min(width - self.right_column.minimumSizeHint().width(), width / 2) left_width = min(width - self.right_column.minimumSizeHint().width(), width // 2)
left_width = max(left_width, self.left_column.minimumSizeHint().width()) left_width = max(left_width, self.left_column.minimumSizeHint().width())
self.left_column.setFixedWidth(left_width) self.left_column.setFixedWidth(left_width)

View File

@ -35,6 +35,7 @@ Some of the code for this form is based on the examples at:
* `http://html5demos.com/two-videos`_ * `http://html5demos.com/two-videos`_
""" """
from __future__ import division
import cgi import cgi
import logging import logging
import sys import sys
@ -207,8 +208,8 @@ class MainDisplay(Display):
painter_image.begin(self.initial_fame) painter_image.begin(self.initial_fame)
painter_image.fillRect(self.initial_fame.rect(), background_color) painter_image.fillRect(self.initial_fame.rect(), background_color)
painter_image.drawImage( painter_image.drawImage(
(self.screen[u'size'].width() - splash_image.width()) / 2, (self.screen[u'size'].width() - splash_image.width()) // 2,
(self.screen[u'size'].height() - splash_image.height()) / 2, (self.screen[u'size'].height() - splash_image.height()) // 2,
splash_image) splash_image)
service_item = ServiceItem() service_item = ServiceItem()
service_item.bg_image_bytes = image_to_byte(self.initial_fame) service_item.bg_image_bytes = image_to_byte(self.initial_fame)
@ -268,7 +269,7 @@ class MainDisplay(Display):
self.resize(self.width(), alert_height) self.resize(self.width(), alert_height)
self.setVisible(True) self.setVisible(True)
if location == AlertLocation.Middle: if location == AlertLocation.Middle:
self.move(self.screen[u'size'].left(), (self.screen[u'size'].height() - alert_height) / 2) self.move(self.screen[u'size'].left(), (self.screen[u'size'].height() - alert_height) // 2)
elif location == AlertLocation.Bottom: elif location == AlertLocation.Bottom:
self.move(self.screen[u'size'].left(), self.screen[u'size'].height() - alert_height) self.move(self.screen[u'size'].left(), self.screen[u'size'].height() - alert_height)
else: else:

View File

@ -29,6 +29,8 @@
""" """
The Themes configuration tab The Themes configuration tab
""" """
from __future__ import division
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Registry, Settings, SettingsTab, UiStrings, translate from openlp.core.lib import Registry, Settings, SettingsTab, UiStrings, translate
@ -90,7 +92,7 @@ class ThemesTab(SettingsTab):
self.global_level_label.setObjectName(u'global_level_label') self.global_level_label.setObjectName(u'global_level_label')
self.level_layout.addRow(self.global_level_radio_button, self.global_level_label) self.level_layout.addRow(self.global_level_radio_button, self.global_level_label)
label_top_margin = (self.song_level_radio_button.sizeHint().height() - label_top_margin = (self.song_level_radio_button.sizeHint().height() -
self.song_level_label.sizeHint().height()) / 2 self.song_level_label.sizeHint().height()) // 2
for label in [self.song_level_label, self.service_level_label, self.global_level_label]: for label in [self.song_level_label, self.service_level_label, self.global_level_label]:
rect = label.rect() rect = label.rect()
rect.setTop(rect.top() + label_top_margin) rect.setTop(rect.top() + label_top_margin)

View File

@ -1,13 +1,20 @@
""" """
Package to test the openlp.core.lib package. Package to test the openlp.core.lib package.
""" """
import os
from unittest import TestCase from unittest import TestCase
from datetime import datetime, timedelta from datetime import datetime, timedelta
from mock import MagicMock, patch from mock import MagicMock, patch
from PyQt4 import QtCore, QtGui
from openlp.core.lib import str_to_bool, create_thumb, translate, check_directory_exists, get_text_file_string, \
build_icon, image_to_byte, check_item_selected, validate_thumb, create_separated_list, clean_tags, expand_tags
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources'))
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
image_to_byte, check_item_selected, validate_thumb, create_separated_list, clean_tags, expand_tags
class TestLib(TestCase): class TestLib(TestCase):
@ -125,7 +132,7 @@ class TestLib(TestCase):
Test the check_directory_exists() function Test the check_directory_exists() function
""" """
with patch(u'openlp.core.lib.os.path.exists') as mocked_exists, \ with patch(u'openlp.core.lib.os.path.exists') as mocked_exists, \
patch(u'openlp.core.lib.os.makedirs') as mocked_makedirs: patch(u'openlp.core.lib.os.makedirs') as mocked_makedirs:
# GIVEN: A directory to check and a mocked out os.makedirs and os.path.exists # GIVEN: A directory to check and a mocked out os.makedirs and os.path.exists
directory_to_check = u'existing/directory' directory_to_check = u'existing/directory'
@ -219,7 +226,7 @@ class TestLib(TestCase):
Test the build_icon() function with a resource URI Test the build_icon() function with a resource URI
""" """
with patch(u'openlp.core.lib.QtGui') as MockedQtGui, \ with patch(u'openlp.core.lib.QtGui') as MockedQtGui, \
patch(u'openlp.core.lib.QtGui.QPixmap') as MockedQPixmap: patch(u'openlp.core.lib.QtGui.QPixmap') as MockedQPixmap:
# GIVEN: A mocked QIcon and a mocked QPixmap # GIVEN: A mocked QIcon and a mocked QPixmap
MockedQtGui.QIcon = MagicMock MockedQtGui.QIcon = MagicMock
MockedQtGui.QIcon.Normal = 1 MockedQtGui.QIcon.Normal = 1
@ -261,9 +268,43 @@ class TestLib(TestCase):
mocked_byte_array.toBase64.assert_called_with() mocked_byte_array.toBase64.assert_called_with()
assert result == u'base64mock', u'The result should be the return value of the mocked out base64 method' assert result == u'base64mock', u'The result should be the return value of the mocked out base64 method'
def create_thumb_with_size_test(self):
"""
Test the create_thumb() function
"""
# GIVEN: An image to create a thumb of.
image_path = os.path.join(TEST_PATH, u'church.jpg')
thumb_path = os.path.join(TEST_PATH, u'church_thumb.jpg')
thumb_size = QtCore.QSize(10, 20)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
os.remove(thumb_path)
except:
pass
# Only continue when the thumb does not exist.
assert not os.path.exists(thumb_path), u'Test was not ran, because the thumb already exists.'
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path, size=thumb_size)
# THEN: Check if the thumb was created.
assert os.path.exists(thumb_path), u'Test was not ran, because the thumb already exists.'
assert isinstance(icon, QtGui.QIcon), u'The icon should be a QIcon.'
assert not icon.isNull(), u'The icon should not be null.'
assert QtGui.QImageReader(thumb_path).size() == thumb_size, u'The thumb should have the given size.'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
os.remove(thumb_path)
except:
pass
def check_item_selected_true_test(self): def check_item_selected_true_test(self):
""" """
Test that the check_item_selected() function returns True when there are selected indexes. Test that the check_item_selected() function returns True when there are selected indexes
""" """
# GIVEN: A mocked out QtGui module and a list widget with selected indexes # GIVEN: A mocked out QtGui module and a list widget with selected indexes
MockedQtGui = patch(u'openlp.core.lib.QtGui') MockedQtGui = patch(u'openlp.core.lib.QtGui')
@ -423,7 +464,7 @@ class TestLib(TestCase):
def create_separated_list_qlocate_test(self): def create_separated_list_qlocate_test(self):
""" """
Test the create_separated_list function using the Qt provided method. Test the create_separated_list function using the Qt provided method
""" """
with patch(u'openlp.core.lib.Qt') as mocked_qt, \ with patch(u'openlp.core.lib.Qt') as mocked_qt, \
patch(u'openlp.core.lib.QtCore.QLocale.createSeparatedList') as mocked_createSeparatedList: patch(u'openlp.core.lib.QtCore.QLocale.createSeparatedList') as mocked_createSeparatedList:
@ -442,7 +483,7 @@ class TestLib(TestCase):
def create_separated_list_empty_list_test(self): def create_separated_list_empty_list_test(self):
""" """
Test the create_separated_list function with an empty list. Test the create_separated_list function with an empty list
""" """
with patch(u'openlp.core.lib.Qt') as mocked_qt: with patch(u'openlp.core.lib.Qt') as mocked_qt:
# GIVEN: An empty list and the mocked Qt module. # GIVEN: An empty list and the mocked Qt module.
@ -458,7 +499,7 @@ class TestLib(TestCase):
def create_separated_list_with_one_item_test(self): def create_separated_list_with_one_item_test(self):
""" """
Test the create_separated_list function with a list consisting of only one entry. Test the create_separated_list function with a list consisting of only one entry
""" """
with patch(u'openlp.core.lib.Qt') as mocked_qt: with patch(u'openlp.core.lib.Qt') as mocked_qt:
# GIVEN: A list with a string and the mocked Qt module. # GIVEN: A list with a string and the mocked Qt module.
@ -474,7 +515,7 @@ class TestLib(TestCase):
def create_separated_list_with_two_items_test(self): def create_separated_list_with_two_items_test(self):
""" """
Test the create_separated_list function with a list of two entries. Test the create_separated_list function with a list of two entries
""" """
with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate: with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate:
# GIVEN: A list of strings and the mocked Qt module. # GIVEN: A list of strings and the mocked Qt module.
@ -491,7 +532,7 @@ class TestLib(TestCase):
def create_separated_list_with_three_items_test(self): def create_separated_list_with_three_items_test(self):
""" """
Test the create_separated_list function with a list of three items. Test the create_separated_list function with a list of three items
""" """
with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate: with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate:
# GIVEN: A list with a string and the mocked Qt module. # GIVEN: A list with a string and the mocked Qt module.