Updated to trunk:HEAD

This commit is contained in:
Raoul Snyman 2010-01-29 23:12:14 +02:00
commit 965902544f
28 changed files with 785 additions and 359 deletions

View File

@ -28,13 +28,13 @@ import os
import sys
import logging
from logging.handlers import RotatingFileHandler
from logging import FileHandler
from optparse import OptionParser
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, str_to_bool
from openlp.core.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen
from openlp.core.ui import MainWindow, SplashScreen, ScreenList
from openlp.core.utils import ConfigHelper
log = logging.getLogger()
@ -68,6 +68,10 @@ class OpenLP(QtGui.QApplication):
global log
log.info(u'OpenLP Application Loaded')
def notify(self, obj, evt):
#TODO needed for presentation exceptions
return QtGui.QApplication.notify(self, obj, evt)
def run(self):
"""
Run the OpenLP application.
@ -117,10 +121,10 @@ class OpenLP(QtGui.QApplication):
self.splash.show()
# make sure Qt really display the splash screen
self.processEvents()
screens = []
screens = ScreenList()
# Decide how many screens we have and their size
for screen in xrange(0, self.desktop().numScreens()):
screens.append({u'number': screen,
screens.add_screen({u'number': screen,
u'size': self.desktop().availableGeometry(screen),
u'primary': (self.desktop().primaryScreen() == screen)})
log.info(u'Screen %d found with resolution %s',
@ -131,6 +135,7 @@ class OpenLP(QtGui.QApplication):
if show_splash:
# now kill the splashscreen
self.splash.finish(self.mainWindow)
self.mainWindow.repaint()
self.mainWindow.versionCheck()
return self.exec_()
@ -154,7 +159,7 @@ def main():
help="Set the Qt4 style (passed directly to Qt4).")
# Set up logging
filename = u'openlp.log'
logfile = RotatingFileHandler(filename, maxBytes=200000, backupCount=5)
logfile = FileHandler(filename)
logfile.setFormatter(logging.Formatter(
u'%(asctime)s %(name)-15s %(levelname)-8s %(message)s'))
log.addHandler(logfile)

View File

@ -136,6 +136,26 @@ def contextMenuSeparator(base):
action.setSeparator(True)
return action
def resize_image(image, width, height):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
"""
preview = QtGui.QImage(image)
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width();
realh = preview.height()
# and move it to the centre of the preview space
newImage = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
newImage.fill(QtCore.Qt.black)
painter = QtGui.QPainter(newImage)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
return newImage
class ThemeLevel(object):
Global = 1
Service = 2
@ -160,6 +180,3 @@ from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
from baselistwithdnd import BaseListWithDnD
#__all__ = [ 'translate', 'get_text_file_string', 'str_to_bool',
# 'contextMenuAction', 'contextMenuSeparator', 'ServiceItem']

View File

@ -26,6 +26,7 @@
import logging
from PyQt4 import QtGui, QtCore
from openlp.core.lib import resize_image
class Renderer(object):
"""
@ -41,7 +42,7 @@ class Renderer(object):
Initialise the renderer.
"""
self._rect = None
self._debug = 0
self._debug = False
self._right_margin = 64 # the amount of right indent
self._display_shadow_size_footer = 0
self._display_outline_size_footer = 0
@ -90,31 +91,9 @@ class Renderer(object):
log.debug(u'set bg image %s', filename)
self._bg_image_filename = unicode(filename)
if self._frame:
self.scale_bg_image()
def scale_bg_image(self):
"""
Scale the background image to fit the screen.
"""
assert self._frame
preview = QtGui.QImage(self._bg_image_filename)
width = self._frame.width()
height = self._frame.height()
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realwidth = preview.width()
realheight = preview.height()
# and move it to the centre of the preview space
self.bg_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied)
self.bg_image.fill(QtCore.Qt.black)
painter = QtGui.QPainter()
painter.begin(self.bg_image)
self.background_offsetx = (width - realwidth) / 2
self.background_offsety = (height - realheight) / 2
painter.drawImage(self.background_offsetx,
self.background_offsety, preview)
painter.end()
self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(),
self._frame.height())
def set_frame_dest(self, frame_width, frame_height, preview=False):
"""
@ -138,7 +117,9 @@ class Renderer(object):
self._frameOp = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename and not self.bg_image:
self.scale_bg_image()
self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(),
self._frame.height())
if self.bg_frame is None:
self._generate_background_frame()
@ -167,17 +148,22 @@ class Renderer(object):
def pre_render_text(self, text):
metrics = QtGui.QFontMetrics(self.mainFont)
#take the width work out approx how many characters and add 50%
#work out line width
line_width = self._rect.width() - self._right_margin
#number of lines on a page - adjust for rounding up.
page_length = int(self._rect.height() / metrics.height() - 2 ) - 1
line_height = metrics.height()
if self._theme.display_shadow:
line_height += int(self._theme.display_shadow_size)
if self._theme.display_outline:
# pixels top/bottom
line_height += 2 * int(self._theme.display_outline_size)
page_length = int(self._rect.height() / line_height )
#Average number of characters in line
ave_line_width = line_width / metrics.averageCharWidth()
#Maximum size of a character
max_char_width = metrics.maxWidth()
#Min size of a character
min_char_width = metrics.width(u'i')
char_per_line = line_width / min_char_width
#Max characters pre line based on min size of a character
char_per_line = line_width / metrics.width(u'i')
log.debug(u'Page Length area height %s , metrics %s , lines %s' %
(int(self._rect.height()), metrics.height(), page_length ))
split_pages = []
@ -276,8 +262,13 @@ class Renderer(object):
Results are cached for performance reasons.
"""
assert(self._theme)
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
if self._theme.background_mode == u'transparent':
self.bg_frame = \
QtGui.QPixmap(self._frame.width(), self._frame.height())
self.bg_frame.fill(QtCore.Qt.transparent)
else:
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
log.debug(u'render background %s start', self._theme.background_type)
painter = QtGui.QPainter()
painter.begin(self.bg_frame)
@ -422,6 +413,14 @@ class Renderer(object):
startx = x
starty = y
rightextent = None
self.painter = QtGui.QPainter()
self.painter.begin(self._frame)
self.painter.setRenderHint(QtGui.QPainter.Antialiasing);
if self._theme.display_slideTransition:
self.painter2 = QtGui.QPainter()
self.painter2.begin(self._frameOp)
self.painter2.setRenderHint(QtGui.QPainter.Antialiasing);
self.painter2.setOpacity(0.7)
# dont allow alignment messing with footers
if footer:
align = 0
@ -503,13 +502,14 @@ class Renderer(object):
if linenum == 0:
self._first_line_right_extent = rightextent
# draw a box around the text - debug only
if self._debug:
painter = QtGui.QPainter()
painter.begin(self._frame)
painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0)))
painter.drawRect(startx, starty, rightextent-startx, y-starty)
painter.end()
self.painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0)))
self.painter.drawRect(startx, starty, rightextent-startx, y-starty)
brcorner = (rightextent, y)
self.painter.end()
if self._theme.display_slideTransition:
self.painter2.end()
return brcorner
def _set_theme_font(self):
@ -519,6 +519,7 @@ class Renderer(object):
footer_weight = 50
if self._theme.font_footer_weight == u'Bold':
footer_weight = 75
#TODO Add myfont.setPixelSize((screen_height / 100) * font_size)
self.footerFont = QtGui.QFont(self._theme.font_footer_name,
self._theme.font_footer_proportion, # size
footer_weight, # weight
@ -556,45 +557,36 @@ class Renderer(object):
Defaults to *None*. The colour to draw with.
"""
# setup defaults
painter = QtGui.QPainter()
painter.begin(self._frame)
painter.setRenderHint(QtGui.QPainter.Antialiasing);
if footer :
font = self.footerFont
else:
font = self.mainFont
painter.setFont(font)
self.painter.setFont(font)
if color is None:
if footer:
painter.setPen(QtGui.QColor(self._theme.font_footer_color))
self.painter.setPen(QtGui.QColor(self._theme.font_footer_color))
else:
painter.setPen(QtGui.QColor(self._theme.font_main_color))
self.painter.setPen(QtGui.QColor(self._theme.font_main_color))
else:
painter.setPen(QtGui.QColor(color))
self.painter.setPen(QtGui.QColor(color))
x, y = tlcorner
metrics = QtGui.QFontMetrics(font)
w = metrics.width(line)
h = metrics.height() - 2
h = metrics.height()
if draw:
painter.drawText(x, y + metrics.ascent(), line)
painter.end()
self.painter.drawText(x, y + metrics.ascent(), line)
if self._theme.display_slideTransition:
# Print 2nd image with 70% weight
painter = QtGui.QPainter()
painter.begin(self._frameOp)
painter.setRenderHint(QtGui.QPainter.Antialiasing);
painter.setOpacity(0.7)
painter.setFont(font)
self.painter2.setFont(font)
if color is None:
if footer:
painter.setPen(QtGui.QColor(self._theme.font_footer_color))
self.painter2.setPen(QtGui.QColor(self._theme.font_footer_color))
else:
painter.setPen(QtGui.QColor(self._theme.font_main_color))
self.painter2.setPen(QtGui.QColor(self._theme.font_main_color))
else:
painter.setPen(QtGui.QColor(color))
self.painter2.setPen(QtGui.QColor(color))
if draw:
painter.drawText(x, y + metrics.ascent(), line)
painter.end()
self.painter2.drawText(x, y + metrics.ascent(), line)
return (w, h)
def snoop_Image(self, image, image2=None):
@ -609,4 +601,4 @@ class Renderer(object):
"""
image.save(u'renderer.png', u'png')
if image2:
image2.save(u'renderer2.png', u'png')
image2.save(u'renderer2.png', u'png')

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtGui, QtCore
from renderer import Renderer
from openlp.core.lib import ThemeLevel
from openlp.core.lib import ThemeLevel, resize_image
class RenderManager(object):
"""
@ -39,8 +39,8 @@ class RenderManager(object):
``theme_manager``
The ThemeManager instance, used to get the current theme details.
``screen_list``
The list of screens available.
``screens``
Contains information about the Screens.
``screen_number``
Defaults to *0*. The index of the output/display screen.
@ -49,27 +49,21 @@ class RenderManager(object):
log = logging.getLogger(u'RenderManager')
log.info(u'RenderManager Loaded')
def __init__(self, theme_manager, screen_list, screen_number=0):
def __init__(self, theme_manager, screens, screen_number=0):
"""
Initialise the render manager.
"""
log.debug(u'Initilisation started')
self.screen_list = screen_list
self.screens = screens
self.theme_manager = theme_manager
self.displays = len(screen_list)
if (screen_number + 1) > len(screen_list):
self.current_display = 0
else:
self.current_display = screen_number
self.renderer = Renderer()
self.calculate_default(self.screen_list[self.current_display][u'size'])
self.screens.set_current_display(screen_number)
self.calculate_default(self.screens.current[u'size'])
self.theme = u''
self.service_theme = u''
self.theme_level = u''
self.override_background = None
self.themedata = None
self.save_bg_frame = None
self.override_background_changed = False
def update_display(self, screen_number):
"""
@ -79,10 +73,8 @@ class RenderManager(object):
The updated index of the output/display screen.
"""
log.debug(u'Update Display')
if self.current_display != screen_number:
self.current_display = screen_number
self.calculate_default(
self.screen_list[self.current_display][u'size'])
self.calculate_default(self.screens.current[u'size'])
self.renderer.bg_frame = None
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
"""
@ -137,31 +129,14 @@ class RenderManager(object):
if self.theme != self.renderer.theme_name or self.themedata is None:
log.debug(u'theme is now %s', self.theme)
self.themedata = self.theme_manager.getThemeData(self.theme)
self.calculate_default(
self.screen_list[self.current_display][u'size'])
self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata)
#Replace the backgrount image from renderer with one from image
if self.override_background:
if self.save_bg_frame is None:
self.save_bg_frame = self.renderer.bg_frame
if self.override_background_changed:
self.renderer.bg_frame = self.resize_image(
self.override_background)
self.override_background_changed = False
else:
if self.override_background_changed:
self.renderer.bg_frame = self.resize_image(
self.override_background)
self.override_background_changed = False
if self.save_bg_frame:
self.renderer.bg_frame = self.save_bg_frame
self.save_bg_frame = None
def build_text_rectangle(self, theme):
"""
Builds a text block using the settings in ``theme``.
One is needed per slide
Builds a text block using the settings in ``theme``
and the size of the display screen.height.
``theme``
The theme to build a text block for.
@ -170,14 +145,14 @@ class RenderManager(object):
main_rect = None
footer_rect = None
if not theme.font_main_override:
main_rect = QtCore.QRect(10, 0, self.width - 1,
self.footer_start - 20)
main_rect = QtCore.QRect(10, 0,
self.width - 1, self.footer_start)
else:
main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y,
theme.font_main_width - 1, theme.font_main_height - 1)
if not theme.font_footer_override:
footer_rect = QtCore.QRect(10, self.footer_start, self.width - 1,
self.height-self.footer_start)
footer_rect = QtCore.QRect(10, self.footer_start,
self.width - 1, self.height - self.footer_start)
else:
footer_rect = QtCore.QRect(theme.font_footer_x,
theme.font_footer_y, theme.font_footer_width - 1,
@ -192,10 +167,13 @@ class RenderManager(object):
The theme to generated a preview for.
"""
log.debug(u'generate preview')
self.calculate_default(QtCore.QSize(1024, 768))
#set the default image size for previews
self.calculate_default(self.screens.preview[u'size'])
self.renderer.set_theme(themedata)
self.build_text_rectangle(themedata)
self.renderer.set_frame_dest(self.width, self.height, True)
#Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size'])
verse = u'Amazing Grace!\n'\
'How sweet the sound\n'\
'To save a wretch like me;\n'\
@ -206,6 +184,7 @@ class RenderManager(object):
footer.append(u'Public Domain')
footer.append(u'CCLI 123456')
formatted = self.renderer.format_slide(verse, False)
#Only Render the first slide page returned
return self.renderer.generate_frame_from_lines(formatted[0], footer)[u'main']
def format_slide(self, words):
@ -234,48 +213,18 @@ class RenderManager(object):
self.renderer.set_frame_dest(self.width, self.height)
return self.renderer.generate_frame_from_lines(main_text, footer_text)
def resize_image(self, image, width=0, height=0):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
"""
preview = QtGui.QImage(image)
if width == 0:
w = self.width
h = self.height
else:
w = width
h = height
preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width();
realh = preview.height()
# and move it to the centre of the preview space
newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
newImage.fill(QtCore.Qt.black)
painter = QtGui.QPainter(newImage)
painter.drawImage((w - realw) / 2, (h - realh) / 2, preview)
return newImage
def calculate_default(self, screen):
"""
Calculate the default dimentions of the screen.
``screen``
The QWidget instance of the screen.
The QSize of the screen.
"""
log.debug(u'calculate default %s', screen)
#size fixed so reflects the preview size.
if self.current_display == 0:
self.width = 1024
self.height = 768
else:
self.width = screen.width()
self.height = screen.height()
self.width = screen.width()
self.height = screen.height()
self.screen_ratio = float(self.height) / float(self.width)
log.debug(u'calculate default %d, %d, %f',
self.width, self.height, self.screen_ratio )
# 90% is start of footer
self.footer_start = int(self.height * 0.90)
self.footer_start = int(self.height * 0.90)

View File

@ -30,7 +30,7 @@ import uuid
from PyQt4 import QtGui
from openlp.core.lib import build_icon, Receiver
from openlp.core.lib import build_icon, Receiver, resize_image
class ServiceItemType(object):
"""
@ -102,16 +102,19 @@ class ServiceItem(object):
formated = self.RenderManager.format_slide(slide[u'raw_slide'])
for format in formated:
lines = u''
title = u''
for line in format:
if title == u'':
title = line
lines += line + u'\n'
title = lines.split(u'\n')[0]
self._display_frames.append({u'title': title, \
u'text': lines, u'verseTag': slide[u'verseTag'] })
u'text': lines.rstrip(), u'verseTag': slide[u'verseTag'] })
log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames:
slide[u'image'] = \
self.RenderManager.resize_image(slide[u'image'])
resize_image(slide[u'image'], self.RenderManager.width,
self.RenderManager.height)
elif self.service_item_type == ServiceItemType.Command:
pass
else:
@ -119,7 +122,7 @@ class ServiceItem(object):
def render_individual(self, row):
"""
Takes an array of text and geneates an Image from the
Takes an array of text and generates an Image from the
theme. It assumes the text will fit on the screen as it
has generated by the render method above.
"""
@ -309,4 +312,4 @@ class ServiceItem(object):
def request_audit(self):
if self.audit:
Receiver.send_message(u'songusage_live', self.audit)
Receiver.send_message(u'songusage_live', self.audit)

View File

@ -33,7 +33,7 @@ class SettingsManager(object):
individual components.
"""
def __init__(self, screen):
self.screen = screen[0]
self.screen = screen.current
self.width = self.screen[u'size'].width()
self.height = self.screen[u'size'].height()
self.mainwindow_height = self.height * 0.8
@ -72,4 +72,4 @@ class SettingsManager(object):
u'media manager', isVisible)
def togglePreviewPanel(self, isVisible):
ConfigHelper.set_config(u'user interface', u'preview panel', isVisible)
ConfigHelper.set_config(u'user interface', u'preview panel', isVisible)

View File

@ -23,7 +23,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
#from slidecontroller import MasterToolbar
from screen import ScreenList
from maindisplay import MainDisplay
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController
@ -42,4 +42,4 @@ from mainwindow import MainWindow
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainWindow',
'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
'AmendThemeForm', 'MediaDockManager', 'ThemeLevel']
'AmendThemeForm', 'MediaDockManager', 'ThemeLevel']

View File

@ -694,8 +694,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
if self.allowPreview:
#calculate main number of rows
metrics = self._getThemeMetrics()
line_height = metrics.height()
if self.theme.display_shadow:
line_height += int(self.theme.display_shadow_size)
if self.theme.display_outline:
# pixels top/bottom
line_height += 2 * int(self.theme.display_outline_size)
page_length = \
(self.FontMainHeightSpinBox.value() / metrics.height() - 2) - 1
((self.FontMainHeightSpinBox.value()) / line_height )
log.debug(u'Page Length area height %s, metrics %s, lines %s' %
(self.FontMainHeightSpinBox.value(), metrics.height(),
page_length))
@ -719,4 +725,4 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
if self.theme.font_main_width < metrics.maxWidth() * 2 + 64:
self.theme.font_main_width = metrics.maxWidth() * 2 + 64
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
return metrics
return metrics

View File

@ -183,7 +183,7 @@ class GeneralTab(SettingsTab):
self.Password = self.PasswordEdit.displayText()
def load(self):
for screen in self.screen_list:
for screen in self.screen_list.screen_list:
screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1)
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary'))
@ -215,4 +215,4 @@ class GeneralTab(SettingsTab):
self.config.set_config(u'save prompt', self.PromptSaveService)
self.config.set_config(u'ccli number', self.CCLINumber)
self.config.set_config(u'songselect username', self.Username)
self.config.set_config(u'songselect password', self.Password)
self.config.set_config(u'songselect password', self.Password)

View File

@ -30,7 +30,7 @@ import time
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver
from openlp.core.lib import Receiver, resize_image
class DisplayWidget(QtGui.QWidget):
"""
@ -90,29 +90,28 @@ class MainDisplay(DisplayWidget):
self.parent = parent
self.setWindowTitle(u'OpenLP Display')
self.screens = screens
self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.layout.setObjectName(u'layout')
self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget()
self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.layout.insertWidget(0, self.video)
self.display = QtGui.QLabel(self)
self.display.setScaledContents(True)
self.layout.insertWidget(0, self.display)
self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self)
self.display_text.setScaledContents(True)
self.display_alert = QtGui.QLabel(self)
self.display_alert.setScaledContents(True)
self.primary = True
self.displayBlank = False
self.blankFrame = None
self.frame = None
self.alertactive = False
self.timer_id = 0
self.firstTime = True
self.mediaLoaded = False
self.hasTransition = False
self.alertList = []
self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'alert_text'), self.displayAlert)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -126,11 +125,10 @@ class MainDisplay(DisplayWidget):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPaws)
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
def setup(self, screenNumber):
"""
Sets up the screen on a particular screen.
@ -138,38 +136,51 @@ class MainDisplay(DisplayWidget):
"""
log.debug(u'Setup %s for %s ' %(self.screens, screenNumber))
self.setVisible(False)
screen = self.screens[screenNumber]
if screen[u'number'] != screenNumber:
# We will most probably never actually hit this bit, but just in
# case the index in the list doesn't match the screen number, we
# search for it.
for scrn in self.screens:
if scrn[u'number'] == screenNumber:
screen = scrn
break
self.setGeometry(screen[u'size'])
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
self.alertScreenPosition = self.screen[u'size'].height() * 0.9
self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition
self.display_alert.setGeometry(
QtCore.QRect(0, self.alertScreenPosition,
self.screen[u'size'].width(),self.alertHeight))
self.video.setGeometry(self.screen[u'size'])
self.display_image.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
#Build a custom splash screen
self.InitialFrame = QtGui.QImage(
screen[u'size'].width(), screen[u'size'].height(),
self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png')
painter_image = QtGui.QPainter()
painter_image.begin(self.InitialFrame)
painter_image.fillRect(self.InitialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage(
(screen[u'size'].width() - splash_image.width()) / 2,
(screen[u'size'].height() - splash_image.height()) / 2,
(self.screen[u'size'].width() - splash_image.width()) / 2,
(self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image)
self.frameView(self.InitialFrame)
self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame))
self.repaint()
#Build a Black screen
painter = QtGui.QPainter()
self.blankFrame = QtGui.QImage(
screen[u'size'].width(), screen[u'size'].height(),
self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter.begin(self.blankFrame)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
#TODO make black when testing finished
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red)
#build a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent)
self.frameView(self.transparent)
# To display or not to display?
if not screen[u'primary']:
if not self.screen[u'primary']:
self.showFullScreen()
self.primary = False
else:
@ -179,6 +190,8 @@ class MainDisplay(DisplayWidget):
def resetDisplay(self):
if self.primary:
self.setVisible(False)
else:
self.showFullScreen()
def hideDisplay(self):
self.setVisible(False)
@ -186,6 +199,17 @@ class MainDisplay(DisplayWidget):
def showDisplay(self):
if not self.primary:
self.setVisible(True)
self.showFullScreen()
def addImageWithText(self, frame):
frame = resize_image(frame,
self.screen[u'size'].width(),
self.screen[u'size'].height() )
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
# self.display_image.show()
# if not self.isVisible():
# self.setVisible(True)
# self.showFullScreen()
def frameView(self, frame, transition=False):
"""
@ -194,38 +218,38 @@ class MainDisplay(DisplayWidget):
``frame``
Image frame to be rendered
"""
if self.timer_id != 0 :
self.displayAlert()
elif not self.displayBlank:
if not self.displayBlank:
if transition:
if self.hasTransition:
if self.frame[u'trans'] is not None:
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'trans']))
self.repaint()
if frame[u'trans'] is not None:
self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
self.hasTransition = True
self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
if self.frame is not None:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.frame))
self.repaint()
self.frame = None
if frame[u'trans'] is not None:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
self.frame = frame[u'trans']
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
self.display_frame = frame[u'main']
self.repaint()
else:
self.display.setPixmap(QtGui.QPixmap.fromImage(frame))
if isinstance(frame, QtGui.QPixmap):
self.display_text.setPixmap(frame)
else:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame))
self.display_frame = frame
if not self.isVisible():
self.setVisible(True)
self.showFullScreen()
self.frame = frame
def blankDisplay(self, blanked=True):
if blanked:
self.displayBlank = True
self.display.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
else:
self.displayBlank = False
if self.frame:
self.frameView(self.frame)
if blanked != self.parent.LiveController.blankButton.isChecked():
self.parent.LiveController.blankButton.setChecked(self.displayBlank)
self.parent.generalConfig.set_config(u'screen blank', self.displayBlank)
if self.display_frame:
self.frameView(self.display_frame)
def displayAlert(self, text=u''):
"""
@ -235,17 +259,30 @@ class MainDisplay(DisplayWidget):
display text
"""
log.debug(u'display alert called %s' % text)
self.parent.StatusBar.showMessage(self.trUtf8(u''))
self.alertList.append(text)
if self.timer_id != 0 or self.mediaLoaded:
self.parent.StatusBar.showMessage(\
self.trUtf8(u'Alert message created and delayed'))
return
self.generateAlert()
def generateAlert(self):
log.debug(u'Generate Alert called')
if len(self.alertList) == 0:
return
text = self.alertList.pop(0)
alertTab = self.parent.settingsForm.AlertsTab
if isinstance(self.frame, QtGui.QImage):
alertframe = QtGui.QPixmap.fromImage(self.frame)
else:
alertframe = QtGui.QPixmap.fromImage(self.frame[u'main'])
alertframe = \
QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight)
alertframe.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(alertframe)
top = alertframe.rect().height() * 0.9
painter.fillRect(alertframe.rect(), QtCore.Qt.transparent)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.fillRect(
QtCore.QRect(
0, top, alertframe.rect().width(),
alertframe.rect().height() - top),
0, 0, alertframe.rect().width(),
alertframe.rect().height()),
QtGui.QColor(alertTab.bg_color))
font = QtGui.QFont()
font.setFamily(alertTab.font_face)
@ -253,28 +290,29 @@ class MainDisplay(DisplayWidget):
font.setPointSize(40)
painter.setFont(font)
painter.setPen(QtGui.QColor(alertTab.font_color))
x, y = (0, top)
x, y = (0, 0)
metrics = QtGui.QFontMetrics(font)
painter.drawText(
x, y + metrics.height() - metrics.descent() - 1, text)
painter.end()
self.display.setPixmap(alertframe)
self.display_alert.setPixmap(alertframe)
self.display_alert.setVisible(True)
# check to see if we have a timer running
if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event):
if event.timerId() == self.timer_id:
if isinstance(self.frame, QtGui.QImage):
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame))
else:
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'main']))
self.killTimer(self.timer_id)
self.timer_id = 0
self.display_alert.setPixmap(self.transparent)
self.killTimer(self.timer_id)
self.timer_id = 0
self.generateAlert()
def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message)
self.display.close()
self.display_image.close()
self.display_text.close()
self.display_alert.close()
file = os.path.join(message[1], message[2])
if self.firstTime:
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
@ -287,29 +325,33 @@ class MainDisplay(DisplayWidget):
log.debug(u'Play the new media, Live ')
if not self.mediaLoaded and not self.displayBlank:
self.blankDisplay()
self.display_frame = self.blankFrame
self.firstTime = True
self.mediaLoaded = True
self.display.hide()
self.display_image.hide()
self.display_text.hide()
self.display_alert.hide()
self.video.setFullScreen(True)
self.video.setVisible(True)
self.mediaObject.play()
if self.primary:
self.setVisible(True)
self.setVisible(True)
self.hide()
def onMediaPaws(self):
def onMediaPause(self):
log.debug(u'Media paused by user')
self.mediaObject.pause()
def onMediaStop(self):
log.debug(u'Media stopped by user')
self.mediaObject.stop()
self.onMediaFinish()
def onMediaFinish(self):
log.debug(u'Reached end of media playlist')
if self.primary:
self.setVisible(False)
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaLoaded = False
self.video.setVisible(False)
self.display.show()
self.display_text.show()
self.display_image.show()
self.blankDisplay(False)

View File

@ -50,7 +50,6 @@ media_manager_style = """
border-color: palette(light);
}
"""
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
"""
@ -425,7 +424,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
plugins.
"""
QtGui.QMainWindow.__init__(self)
self.screenList = screens
self.screens = screens
self.applicationVersion = applicationVersion
self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens)
@ -433,7 +432,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.mainDisplay = MainDisplay(self, screens)
self.alertForm = AlertForm(self)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screenList, self, self)
self.settingsForm = SettingsForm(self.screens, self, self)
# Set up the path with plugins
pluginpath = os.path.split(os.path.abspath(__file__))[0]
pluginpath = os.path.abspath(
@ -500,7 +499,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
#RenderManager needs to call ThemeManager and
#ThemeManager needs to call RenderManager
self.RenderManager = RenderManager(self.ThemeManagerContents,
self.screenList, self.getMonitorNumber())
self.screens, self.getMonitorNumber())
#Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
log.info(u'Load Plugins')
@ -545,7 +544,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if app_version != version:
version_text = unicode(self.trUtf8('OpenLP version %s has been updated '
'to version %s\n\nYou can obtain the latest version from http://openlp.org'))
QtGui.QMessageBox.question(None,
QtGui.QMessageBox.question(self,
self.trUtf8('OpenLP Version Updated'),
version_text % (app_version, version),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
@ -558,11 +557,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
monitor number does not exist.
"""
screen_number = int(self.generalConfig.get_config(u'monitor', 0))
monitor_exists = False
for screen in self.screenList:
if screen[u'number'] == screen_number:
monitor_exists = True
if not monitor_exists:
if not self.screens.screen_exists(screen_number):
screen_number = 0
return screen_number
@ -580,12 +575,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.ServiceManagerContents.onLoadService(True)
if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \
and str_to_bool(self.generalConfig.get_config(u'blank warning', False)):
QtGui.QMessageBox.question(None,
self.LiveController.onBlankDisplay(True)
QtGui.QMessageBox.question(self,
self.trUtf8('OpenLP Main Display Blanked'),
self.trUtf8('The Main Display has been blanked out'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
self.LiveController.blankButton.setChecked(True)
def onHelpAboutItemClicked(self):
"""
@ -613,7 +608,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
self.settingsForm.exec_()
updated_display = self.getMonitorNumber()
if updated_display != self.RenderManager.current_display:
if updated_display != self.screens.current_display:
self.screens.set_current_display(updated_display)
self.RenderManager.update_display(updated_display)
self.mainDisplay.setup(updated_display)
self.activateWindow()
@ -623,7 +619,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Hook to close the main window and display windows on exit
"""
if self.serviceNotSaved:
ret = QtGui.QMessageBox.question(None,
ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your service has changed, do you want to save those changes?'),
QtGui.QMessageBox.StandardButtons(
@ -704,4 +700,4 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def togglePreviewPanel(self):
previewBool = self.PreviewController.Panel.isVisible()
self.PreviewController.Panel.setVisible(not previewBool)
self.settingsmanager.togglePreviewPanel(not previewBool)
self.settingsmanager.togglePreviewPanel(not previewBool)

73
openlp/core/ui/screen.py Normal file
View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import logging
class ScreenList(object):
"""
Wrapper to handle the parameters of the display screen
"""
global log
log = logging.getLogger(u'Screen')
log.info(u'Screen loaded')
def __init__(self):
self.preview = None
self.current = None
self.screen_list = []
self.count = 0
self.current_display = 0
def add_screen(self, screen):
if screen[u'primary'] == True:
self.current = screen
self.screen_list.append(screen)
self.count += 1
def screen_exists(self, number):
for screen in self.screen_list:
if screen[u'number'] == number:
return True
return False
def set_current_display(self, number):
if number + 1 > self.count:
self.current = self.screen_list[0]
self.current_display = 0
else:
self.current = self.screen_list[number]
self.preview = self.current
self.current_display = number
if self.count == 1:
self.preview = self.screen_list[0]
# if self.screen[u'number'] != screenNumber:
# # We will most probably never actually hit this bit, but just in
# # case the index in the list doesn't match the screen number, we
# # search for it.
# for scrn in self.screens:
# if scrn[u'number'] == screenNumber:
# self.screen = scrn
# break

View File

@ -348,7 +348,7 @@ class ServiceManager(QtGui.QWidget):
if self.parent.serviceNotSaved and \
str_to_bool(PluginConfig(u'General').
get_config(u'save prompt', u'False')):
ret = QtGui.QMessageBox.question(None,
ret = QtGui.QMessageBox.question(self,
self.trUtf8('Save Changes to Service?'),
self.trUtf8('Your service is unsaved, do you want to save those '
'changes before creating a new one ?'),
@ -697,4 +697,4 @@ class ServiceManager(QtGui.QWidget):
theme = unicode(self.sender().text())
item, count = self.findServiceItem()
self.serviceItems[item][u'service_item'].theme = theme
self.regenerateServiceItems()
self.regenerateServiceItems()

View File

@ -30,7 +30,8 @@ import os
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, PluginConfig
from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \
PluginConfig, resize_image
class SlideList(QtGui.QTableWidget):
"""
@ -163,9 +164,9 @@ class SlideController(QtGui.QWidget):
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.blankButton = self.Toolbar.addToolbarButton(
u'Blank Screen', u':/slides/slide_close.png',
self.trUtf8('Blank Screen'), self.onBlankScreen, True)
self.trUtf8('Blank Screen'), self.onBlankDisplay, True)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_blank'), self.onBlankDisplay)
QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen)
if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
@ -235,6 +236,9 @@ class SlideController(QtGui.QWidget):
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
if not self.isLive:
self.video.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.video.setVisible(False)
self.SlideLayout.insertWidget(0, self.video)
# Actual preview screen
self.SlidePreview = QtGui.QLabel(self)
@ -246,7 +250,8 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.sizePolicy().hasHeightForWidth())
self.SlidePreview.setSizePolicy(sizePolicy)
self.SlidePreview.setFixedSize(
QtCore.QSize(self.settingsmanager.slidecontroller_image,self.settingsmanager.slidecontroller_image / 1.3 ))
QtCore.QSize(self.settingsmanager.slidecontroller_image,
self.settingsmanager.slidecontroller_image / 1.3 ))
self.SlidePreview.setFrameShape(QtGui.QFrame.Box)
self.SlidePreview.setFrameShadow(QtGui.QFrame.Plain)
self.SlidePreview.setLineWidth(1)
@ -257,8 +262,6 @@ class SlideController(QtGui.QWidget):
# Signals
QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected)
if isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay)
@ -441,7 +444,9 @@ class SlideController(QtGui.QWidget):
else:
label = QtGui.QLabel()
label.setMargin(4)
pixmap = self.parent.RenderManager.resize_image(frame[u'image'])
pixmap = resize_image(frame[u'image'],
self.parent.RenderManager.width,
self.parent.RenderManager.height)
label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
@ -480,18 +485,26 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.selectRow(0)
self.onSlideSelected()
def onBlankDisplay(self):
self.blankButton.setChecked(self.parent.mainDisplay.displayBlank)
def onBlankDisplay(self, force=False):
"""
Handle the blank screen button
"""
if force:
self.blankButton.setChecked(True)
self.blankScreen(self.blankButton.isChecked())
self.parent.generalConfig.set_config(u'screen blank',
self.blankButton.isChecked())
def onBlankScreen(self, blanked):
def blankScreen(self, blanked=False):
"""
Blank the screen.
Blank the display screen.
"""
if not self.serviceItem and self.serviceItem.is_command():
if blanked:
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower())
else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
if self.serviceItem is not None:
if self.serviceItem.is_command():
if blanked:
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower())
else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
else:
self.parent.mainDisplay.blankDisplay(blanked)
@ -531,7 +544,7 @@ class SlideController(QtGui.QWidget):
def updatePreview(self):
rm = self.parent.RenderManager
if not rm.screen_list[rm.current_display][u'primary']:
if not rm.screens.current[u'primary']:
# Grab now, but try again in a couple of seconds if slide change is slow
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
@ -543,7 +556,7 @@ class SlideController(QtGui.QWidget):
def grabMainDisplay(self):
rm = self.parent.RenderManager
winid = QtGui.QApplication.desktop().winId()
rect = rm.screen_list[rm.current_display][u'size']
rect = rm.screens.current[u'size']
winimg = QtGui.QPixmap.grabWindow(winid, rect.x(),
rect.y(), rect.width(), rect.height())
self.SlidePreview.setPixmap(winimg)
@ -635,7 +648,7 @@ class SlideController(QtGui.QWidget):
if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \
[item.title, item.service_item_path,
item.get_frame_title(), slideno, self.isLive])
item.get_frame_title(), self.isLive])
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
@ -659,9 +672,9 @@ class SlideController(QtGui.QWidget):
def onMediaStop(self):
if self.isLive:
Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower())
Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive)
else:
self.mediaObject.stop()
self.video.hide()
self.SlidePreview.clear()
self.SlidePreview.show()
self.SlidePreview.clear()
self.SlidePreview.show()

View File

@ -108,6 +108,8 @@ class ThemeManager(QtGui.QWidget):
self.themelist = []
self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
self.checkThemesExists(self.path)
self.thumbPath = os.path.join(self.path, u'.thumbnails')
self.checkThemesExists(self.thumbPath)
self.amendThemeForm.path = self.path
# Last little bits of setting up
self.config = PluginConfig(u'themes')
@ -185,6 +187,7 @@ class ThemeManager(QtGui.QWidget):
self.ThemeListWidget.takeItem(row)
try:
os.remove(os.path.join(self.path, th))
os.remove(os.path.join(self.thumbPath, th))
shutil.rmtree(os.path.join(self.path, theme))
except:
#if not present do not worry
@ -246,25 +249,33 @@ class ThemeManager(QtGui.QWidget):
log.debug(u'Load themes from dir')
self.themelist = []
self.ThemeListWidget.clear()
for root, dirs, files in os.walk(self.path):
for name in files:
if name.endswith(u'.png'):
#check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
(path, filename) = os.path.split(unicode(file))
textName = os.path.splitext(name)[0]
if textName == self.global_theme:
name = u'%s (%s)' % (textName,
self.trUtf8('default'))
else:
name = textName
item_name = QtGui.QListWidgetItem(name)
item_name.setIcon(build_icon(theme))
item_name.setData(QtCore.Qt.UserRole,
QtCore.QVariant(textName))
self.ThemeListWidget.addItem(item_name)
self.themelist.append(textName)
#root, dirs, files = os.walk(self.path)
dirList = os.listdir(self.path)
for name in dirList:
if name.endswith(u'.png'):
#check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
(path, filename) = os.path.split(unicode(file))
textName = os.path.splitext(name)[0]
if textName == self.global_theme:
name = u'%s (%s)' % (textName,
self.trUtf8('default'))
else:
name = textName
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
item_name = QtGui.QListWidgetItem(name)
if os.path.exists(thumb):
icon = build_icon(thumb)
else:
icon = build_icon(theme)
pixmap = icon.pixmap(QtCore.QSize(88,50))
pixmap.save(thumb, u'png')
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole,
QtCore.QVariant(textName))
self.ThemeListWidget.addItem(item_name)
self.themelist.append(textName)
self.pushThemes()
def pushThemes(self):
@ -427,8 +438,6 @@ class ThemeManager(QtGui.QWidget):
if outfile:
outfile.close()
if image_from and image_from != image_to:
print "if", image_from
print "it", image_to
try:
shutil.copyfile(image_from, image_to)
except:
@ -448,6 +457,10 @@ class ThemeManager(QtGui.QWidget):
if os.path.exists(samplepathname):
os.unlink(samplepathname)
frame.save(samplepathname, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
icon = build_icon(frame)
pixmap = icon.pixmap(QtCore.QSize(88,50))
pixmap.save(thumb, u'png')
log.debug(u'Theme image written to %s', samplepathname)
def generateImage(self, themedata):
@ -529,4 +542,4 @@ class ThemeManager(QtGui.QWidget):
theme.font_main_y = int(theme.font_main_y.strip())
#theme.theme_mode
theme.theme_name = theme.theme_name.strip()
#theme.theme_version
#theme.theme_version

View File

@ -207,6 +207,7 @@ class HTTPBible(BibleDB):
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
"""
Receiver.send_message(u'bible_showprogress')
for reference in reference_list:
log.debug('Reference: %s', reference)
book = reference[0]
@ -228,6 +229,7 @@ class HTTPBible(BibleDB):
db_book = self.get_book(bookname)
self.create_chapter(db_book.id, search_results.get_chapter(),
search_results.get_verselist())
Receiver.send_message(u'bible_hideprogress')
return BibleDB.get_verses(self, reference_list)
def get_chapter(self, version, book, chapter):

View File

@ -247,7 +247,9 @@ class BibleMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Other stuff
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u''))
QtCore.SIGNAL(u'bible_showprogress'), self.onSearchProgressShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_hideprogress'), self.onSearchProgressHide)
def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self)
@ -341,13 +343,13 @@ class BibleMediaItem(MediaManagerItem):
(self.ListView.geometry().y() + self.ListView.geometry().height())\
- 23, 81, 23)
def onSearchProgressShow(self, value):
def onSearchProgressShow(self):
self.SearchProgress.setVisible(True)
self.SearchProgress.setValue(value)
self.SearchProgress.setMinimum(0)
self.SearchProgress.setMaximum(0)
def onSearchProgressHide(self, value):
self.SearchProgress.setVisible(True)
self.SearchProgress.setValue(value)
def onSearchProgressHide(self):
self.SearchProgress.setVisible(False)
def onAdvancedVersionComboBox(self):
self.initialiseBible(

View File

@ -172,7 +172,6 @@ class ImageMediaItem(MediaManagerItem):
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
self.OverrideLabel.setText(bitem.text())
frame = QtGui.QImage(unicode(filename))
self.parent.render_manager.override_background = frame
self.parent.render_manager.override_background_changed = True
self.parent.live_controller.parent.mainDisplay.addImageWithText(frame)
else:
MediaManagerItem.onPreviewClick(self)
MediaManagerItem.onPreviewClick(self)

View File

@ -61,8 +61,9 @@ class MediaMediaItem(MediaManagerItem):
def retranslateUi(self):
self.OnNewPrompt = self.trUtf8('Select Media')
self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg'
'*.mp4);;Audio (*.ogg *.mp3 *.wma);;All files (*)')
self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg *.wmv '
'*.mov *.mp4 *.flv);;Audio (*.ogg *.mp3 *.wma *.wav *.flac)'
';;All files (*)')
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
@ -84,7 +85,7 @@ class MediaMediaItem(MediaManagerItem):
for item in items:
bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
frame = u':/media/media_video.png'
frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename)
service_item.add_from_command(path, name, frame)
return True
@ -110,4 +111,4 @@ class MediaMediaItem(MediaManagerItem):
img = self.video_get_preview()
item_name.setIcon(build_icon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.ListView.addItem(item_name)
self.ListView.addItem(item_name)

View File

@ -145,7 +145,7 @@ class ImpressController(PresentationController):
log.exception(u'Failed to load presentation')
return
self.presentation = self.document.getPresentation()
self.presentation.Display = self.plugin.render_manager.current_display + 1
self.presentation.Display = self.plugin.render_manager.screens.current_display + 1
self.controller = None
self.create_thumbnails()
@ -169,8 +169,12 @@ class ImpressController(PresentationController):
for idx in range(pages.getCount()):
page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page)
doc.storeToURL(thumbdir + u'/' + self.thumbnailprefix +
unicode(idx+1) + u'.png', props)
path = u'%s/%s%s.png'% (thumbdir, self.thumbnailprefix,
unicode(idx+1))
try:
doc.storeToURL(path , props)
except:
log.exception(u'%s\nUnable to store preview' % path)
def create_property(self, name, value):
if os.name == u'nt':
@ -228,9 +232,13 @@ class ImpressController(PresentationController):
"""
if self.document:
if self.presentation:
self.presentation.end()
self.presentation = None
self.document.dispose()
try:
self.presentation.end()
self.presentation = None
self.document.dispose()
except:
#We tried!
pass
self.document = None
def is_loaded(self):
@ -248,7 +256,7 @@ class ImpressController(PresentationController):
return False
if self.controller is None:
return False
return self.controller.isRunning() and self.controller.isActive()
return True
def unblank_screen(self):
return self.controller.resume()
@ -305,4 +313,4 @@ class ImpressController(PresentationController):
if os.path.isfile(path):
return path
else:
return None
return None

View File

@ -47,7 +47,7 @@ class Controller(object):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
self.controller = controller
if self.controller.is_loaded():
self.shutdown(None)
self.shutdown()
self.controller.load_presentation(file)
if self.isLive:
self.controller.start_presentation()
@ -73,55 +73,51 @@ class Controller(object):
self.controller.goto_slide(int(slide) + 1)
self.controller.poll_slidenumber(live)
def first(self, message):
def first(self):
"""
Based on the handler passed at startup triggers the first slide
"""
log.debug(u'Live = %s, first' % self.isLive)
print "first ", message
if not self.isLive:
return
self.activate()
self.controller.start_presentation()
self.controller.poll_slidenumber(self.isLive)
def last(self, message):
def last(self):
"""
Based on the handler passed at startup triggers the first slide
"""
log.debug(u'Live = %s, last' % self.isLive)
print "last ", message
if not self.isLive:
return
self.activate()
self.controller.goto_slide(self.controller.get_slide_count())
self.controller.poll_slidenumber(self.isLive)
def next(self, message):
def next(self):
"""
Based on the handler passed at startup triggers the next slide event
"""
log.debug(u'Live = %s, next' % self.isLive)
print "next ", message
if not self.isLive:
return
self.activate()
self.controller.next_step()
self.controller.poll_slidenumber(self.isLive)
def previous(self, message):
def previous(self):
"""
Based on the handler passed at startup triggers the previous slide event
"""
log.debug(u'Live = %s, previous' % self.isLive)
if not self.isLive:
return
print "previous ", message
self.activate()
self.controller.previous_step()
self.controller.poll_slidenumber(self.isLive)
def shutdown(self, message):
def shutdown(self):
"""
Based on the handler passed at startup triggers slide show to shut down
"""
@ -159,7 +155,6 @@ class MessageListener(object):
self.controllers = controllers
self.previewHandler = Controller(False)
self.liveHandler = Controller(True)
self.isLive = None
# messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup)
@ -202,36 +197,36 @@ class MessageListener(object):
else:
self.previewHandler.slide(slide, live)
def first(self, message):
if self.isLive:
self.liveHandler.first(message)
def first(self, isLive):
if isLive:
self.liveHandler.first()
else:
self.previewHandler.first(message)
self.previewHandler.first()
def last(self, message):
if self.isLive:
self.liveHandler.last(message)
def last(self, isLive):
if isLive:
self.liveHandler.last()
else:
self.previewHandler.last(message)
self.previewHandler.last()
def next(self, message):
if self.isLive:
self.liveHandler.next(message)
def next(self, isLive):
if isLive:
self.liveHandler.next()
else:
self.previewHandler.next(message)
self.previewHandler.next()
def previous(self, message):
if self.isLive:
self.liveHandler.previous(message)
def previous(self, isLive):
if isLive:
self.liveHandler.previous()
else:
self.previewHandler.previous(message)
self.previewHandler.previous()
def shutdown(self, message):
if self.isLive:
self.liveHandler.shutdown(message)
def shutdown(self, isLive):
if isLive:
self.liveHandler.shutdown()
Receiver.send_message(u'live_slide_show')
else:
self.previewHandler.shutdown(message)
self.previewHandler.shutdown()
def blank(self):
if self.isLive:
@ -268,4 +263,4 @@ class MessageListener(object):
return message[0], file, message[4]
def timeout(self):
self.controller.poll_slidenumber(self.is_live)
self.controller.poll_slidenumber(self.is_live)

View File

@ -33,11 +33,11 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
"""
Class documentation goes here.
"""
def __init__(self, auditmanager, parent=None):
def __init__(self, songusagemanager, parent=None):
"""
Constructor
"""
self.auditmanager = auditmanager
self.songusagemanager = songusagemanager
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
@ -52,5 +52,5 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
if ret == QtGui.QMessageBox.Ok:
qDeleteDate = self.DeleteCalendar.selectedDate()
deleteDate = date(qDeleteDate.year(), qDeleteDate.month(), qDeleteDate.day())
self.auditmanager.delete_to_date(deleteDate)
self.close()
self.songusagemanager.delete_to_date(deleteDate)
self.close()

View File

@ -25,10 +25,14 @@
import os
from PyQt4 import QtCore, QtGui
import logging
from songusagedetaildialog import Ui_SongUsageDetailDialog
class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
global log
log = logging.getLogger(u'SongUsageDetailForm')
log.info(u'SongUsage Detail Form loaded')
"""
Class documentation goes here.
"""
@ -106,19 +110,19 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
self.close()
def detailedReport(self):
print "detailed"
filename = u'audit_det_%s_%s.txt' % \
log.debug(u'Detailed report generated')
filename = u'usage_detail_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
audits = self.parent.auditmanager.get_all_audits()
usage = self.parent.songusagemanager.get_all_songusage()
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
file = None
try:
file = open(outname, u'w')
for audit in audits:
for instance in usage:
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \
(audit.auditdate,audit.audittime, audit.title,
audit.copyright, audit.ccl_number , audit.authors)
(instance.usagedate,instance.usagetime, instance.title,
instance.copyright, instance.ccl_number , instance.authors)
file.write(record)
except:
log.exception(u'Failed to write out audit records')
@ -127,8 +131,7 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
file.close()
def summaryReport(self):
print "summary"
log.debug(u'Summary report generated')
filename = u'audit_sum_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
print filename

View File

@ -141,7 +141,7 @@ class SongUsagePlugin(Plugin):
SongUsageitem.authors = u''
for author in SongUsageData[1]:
SongUsageitem.authors += author + u' '
self.songusagemanager.insert_SongUsage(SongUsageitem)
self.songusagemanager.insert_songusage(SongUsageitem)
def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_()
@ -154,4 +154,4 @@ class SongUsagePlugin(Plugin):
about_text = self.trUtf8('<b>SongUsage Plugin</b><br>This plugin '
'records the use of songs and when they have been used during '
'a live service')
return about_text
return about_text

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

@ -108,6 +108,7 @@
<file>media_video.png</file>
<file>media_time.png</file>
<file>media_stop.png</file>
<file>image_clapperboard.png</file>
</qresource>
<qresource prefix="messagebox" >
<file>messagebox_critical.png</file>

306
scripts/bible-1to2-converter.py Executable file
View File

@ -0,0 +1,306 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import sys
import os
import sqlite
import sqlite3
import re
from optparse import OptionParser
from traceback import format_tb as get_traceback
# Some global options to be used throughout the import process
verbose = False
debug = False
old_cursor = None
new_cursor = None
# SQL create statments
create_statements = [
(u'table "book"', u"""CREATE TABLE book (
id INTEGER NOT NULL,
testament_id INTEGER,
name VARCHAR(30),
abbreviation VARCHAR(5),
PRIMARY KEY (id),
FOREIGN KEY(testament_id) REFERENCES testament (id)
)"""),
(u'table "metadata"', u"""CREATE TABLE metadata (
"key" VARCHAR(255) NOT NULL,
value VARCHAR(255),
PRIMARY KEY ("key")
)"""),
(u'table "testament"', u"""CREATE TABLE testament (
id INTEGER NOT NULL,
name VARCHAR(30),
PRIMARY KEY (id)
)"""),
(u'table "verse"', u"""CREATE TABLE verse (
id INTEGER NOT NULL,
book_id INTEGER,
chapter INTEGER,
verse INTEGER,
text TEXT,
PRIMARY KEY (id),
FOREIGN KEY(book_id) REFERENCES book (id)
)"""),
(u'index "idx_abbrev"',
u"""CREATE INDEX idx_abbrev ON book (abbreviation, id)"""),
(u'index "idx_chapter_verse_book',
u"""CREATE INDEX idx_chapter_verse_book ON verse (chapter, verse, book_id, id)"""),
(u'index "idx_chapter_verse_text"',
u"""CREATE INDEX idx_chapter_verse_text ON verse (text, verse, book_id, id)"""),
(u'index "idx_name"',
u"""CREATE INDEX idx_name ON book (name, id)""")
]
def display_sql(sql, params):
prepared_params = []
for param in params:
if isinstance(param, basestring):
prepared_params.append(u'"%s"' % param)
elif isinstance(param, (int, long)):
prepared_params.append(u'%d' % param)
elif isinstance(param, (float, complex)):
prepared_params.append(u'%f' % param)
else:
prepared_params.append(u'"%s"' % str(param))
for prepared_param in prepared_params:
sql = sql.replace(u'?', prepared_param, 1)
return sql
def create_database():
global new_cursor, create_statements
if debug or verbose:
print 'Creating new database:'
else:
print 'Creating new database...',
for statement_type, sql_create in create_statements:
if debug:
print '... ', sql_create.replace('\n', ' ').replace(' ', ' ')
elif verbose:
print '... creating %s...' % statement_type,
new_cursor.execute(sql_create)
if verbose and not debug:
print 'done.'
if not verbose and not debug:
print 'done.'
def import_bible():
global old_cursor, new_cursor, debug, verbose
if debug or verbose:
print 'Importing metadata:'
else:
print 'Importing metadata...',
if debug:
print '... SELECT "key", "value" FROM metadata'
elif verbose:
print '... fetching metadata from old database...',
old_cursor.execute(u'SELECT "key", "value" FROM metadata')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
key = unicode(row[0], u'cp1252')
value = unicode(row[1], u'cp1252')
sql_insert = u'INSERT INTO metadata '\
'("key", "value") '\
'VALUES (?, ?)'
sql_params = (key, value)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % key
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing testaments:'
else:
print 'Importing testaments...',
if debug:
print '... SELECT id, name FROM testament'
elif verbose:
print '... fetching testaments from old database...',
old_cursor.execute(u'SELECT id, name FROM testament')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
id = int(row[0])
name = unicode(row[1], u'cp1252')
sql_insert = u'INSERT INTO testament '\
'(id, name) '\
'VALUES (?, ?)'
sql_params = (id, name)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing books:'
else:
print 'Importing books...',
if debug:
print '... SELECT id, testament_id, name, abbreviation FROM book'
elif verbose:
print '... fetching books from old database...',
old_cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
book_map = {}
for row in rows:
testament_id = int(row[1])
name = unicode(row[2], u'cp1252')
abbreviation = unicode(row[3], u'cp1252')
sql_insert = u'INSERT INTO book '\
'(id, testament_id, name, abbreviation) '\
'VALUES (NULL, ?, ?, ?)'
sql_params = (testament_id, name, abbreviation)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
book_map[row[0]] = new_cursor.lastrowid
if debug:
print ' >>> (old) books.id =', row[0], ' (new) books.id =', book_map[row[0]]
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing verses:'
else:
print 'Importing verses...',
if debug:
print '... SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse...',
elif verbose:
print '... fetching verses from old database...',
old_cursor.execute(u'SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse')
rows = old_cursor.fetchall()
if debug or verbose:
print 'done.'
song_map = {}
for row in rows:
book_id = int(row[1])
chapter = int(row[2])
verse = int(row[3])
text = unicode(row[4], u'cp1252')
sql_insert = u'INSERT INTO verse '\
'(id, book_id, chapter, verse, text) '\
'VALUES (NULL, ?, ?, ?, ?)'
sql_params = (book_map[book_id], chapter, verse, text)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s..."' % text[:17]
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
def main(old_db, new_db):
global old_cursor, new_cursor, debug
old_connection = None
new_connection = None
try:
old_connection = sqlite.connect(old_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem connecting to the old database:', errormsg
return 1
try:
new_connection = sqlite3.connect(new_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the new database:', errormsg
return 1
old_cursor = old_connection.cursor()
new_cursor = new_connection.cursor()
try:
create_database()
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the database:', errormsg
return 1
try:
import_bible()
new_connection.commit()
except:
new_connection.rollback()
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem importing songs:', errormsg
return 1
print 'Import complete.'
if __name__ == u'__main__':
option_parser = OptionParser(usage='Usage: %prog [options] OLDDATABASE NEWDATABASE')
option_parser.add_option('-o', '--overwrite', dest='overwrite', default=False,
action=u'store_true', help='Overwrite database file if it already exists.')
option_parser.add_option('-v', '--verbose', dest='verbose', default=False,
action=u'store_true', help='Outputs additional progress data.')
option_parser.add_option('-d', '--debug', dest='debug', default=False,
action=u'store_true', help='Outputs raw SQL statements (overrides verbose).')
options, arguments = option_parser.parse_args()
if len(arguments) < 2:
if len(arguments) == 0:
option_parser.error('Please specify an old database and a new database.')
else:
option_parser.error('Please specify a new database.')
old_db = os.path.abspath(arguments[0])
new_db = os.path.abspath(arguments[1])
if not os.path.isfile(old_db):
option_parser.error('Old database file ("%s") is not a file.' % old_db)
if not os.path.exists(old_db):
option_parser.error('Old database file ("%s") does not exist.' % old_db)
if os.path.exists(new_db):
if not options.overwrite:
option_parser.error('New database file ("%s") exists. If you want to overwrite it, specify the --overwrite option.' % new_db)
else:
if not os.path.isfile(new_db):
option_parser.error('New database file ("%s") is not a file.' % new_db)
os.unlink(new_db)
verbose = options.verbose
debug = options.debug
main(old_db, new_db)

View File

@ -1 +1 @@
1.9.0-694
1.9.0-698