Warn before importing a theme with a name that already exists

bzr-revno: 1900
This commit is contained in:
Philip Ridout 2012-03-11 16:41:24 +00:00 committed by Jonathan Corwin
commit 0dd0a9b821
1 changed files with 204 additions and 182 deletions

View File

@ -137,13 +137,13 @@ class ThemeManager(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Variables # Variables
self.themelist = [] self.theme_list = []
self.path = AppLocation.get_section_data_path(self.settingsSection) self.path = AppLocation.get_section_data_path(self.settingsSection)
check_directory_exists(self.path) check_directory_exists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails') self.thumb_path = os.path.join(self.path, u'thumbnails')
check_directory_exists(self.thumbPath) check_directory_exists(self.thumb_path)
self.themeForm.path = self.path self.themeForm.path = self.path
self.oldBackgroundImage = None self.old_background_image = None
self.bad_v1_name_chars = re.compile(r'[%+\[\]]') self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
# Last little bits of setting up # Last little bits of setting up
self.configUpdated() self.configUpdated()
@ -175,10 +175,10 @@ class ThemeManager(QtGui.QWidget):
""" """
if item is None: if item is None:
return return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text()) theme_name = unicode(item.text())
# If default theme restrict actions # If default theme restrict actions
if realThemeName == themeName: if real_theme_name == theme_name:
self.deleteToolbarAction.setVisible(True) self.deleteToolbarAction.setVisible(True)
else: else:
self.deleteToolbarAction.setVisible(False) self.deleteToolbarAction.setVisible(False)
@ -191,35 +191,35 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.itemAt(point) item = self.themeListWidget.itemAt(point)
if item is None: if item is None:
return return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text()) theme_name = unicode(item.text())
self.deleteAction.setVisible(False) self.deleteAction.setVisible(False)
self.renameAction.setVisible(False) self.renameAction.setVisible(False)
self.globalAction.setVisible(False) self.globalAction.setVisible(False)
# If default theme restrict actions # If default theme restrict actions
if realThemeName == themeName: if real_theme_name == theme_name:
self.deleteAction.setVisible(True) self.deleteAction.setVisible(True)
self.renameAction.setVisible(True) self.renameAction.setVisible(True)
self.globalAction.setVisible(True) self.globalAction.setVisible(True)
self.menu.exec_(self.themeListWidget.mapToGlobal(point)) self.menu.exec_(self.themeListWidget.mapToGlobal(point))
def changeGlobalFromTab(self, themeName): def changeGlobalFromTab(self, theme_name):
""" """
Change the global theme when it is changed through the Themes settings Change the global theme when it is changed through the Themes settings
tab tab
""" """
log.debug(u'changeGlobalFromTab %s', themeName) log.debug(u'changeGlobalFromTab %s', theme_name)
for count in range (0, self.themeListWidget.count()): for count in range (0, self.themeListWidget.count()):
# reset the old name # reset the old name
item = self.themeListWidget.item(count) item = self.themeListWidget.item(count)
oldName = item.text() old_name = item.text()
newName = unicode(item.data(QtCore.Qt.UserRole).toString()) new_name = unicode(item.data(QtCore.Qt.UserRole).toString())
if oldName != newName: if old_name != new_name:
self.themeListWidget.item(count).setText(newName) self.themeListWidget.item(count).setText(new_name)
# Set the new name # Set the new name
if themeName == newName: if theme_name == new_name:
name = unicode(translate('OpenLP.ThemeManager', name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % newName '%s (default)')) % new_name
self.themeListWidget.item(count).setText(name) self.themeListWidget.item(count).setText(name)
def changeGlobalFromScreen(self, index=-1): def changeGlobalFromScreen(self, index=-1):
@ -231,9 +231,9 @@ class ThemeManager(QtGui.QWidget):
selected_row = self.themeListWidget.currentRow() selected_row = self.themeListWidget.currentRow()
for count in range (0, self.themeListWidget.count()): for count in range (0, self.themeListWidget.count()):
item = self.themeListWidget.item(count) item = self.themeListWidget.item(count)
oldName = item.text() old_name = item.text()
# reset the old name # reset the old name
if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()): if old_name != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.themeListWidget.item(count).setText( self.themeListWidget.item(count).setText(
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
# Set the new name # Set the new name
@ -269,19 +269,19 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')), unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
False, False): False, False):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName) self.fileRenameForm.fileNameEdit.setText(old_theme_name)
if self.fileRenameForm.exec_(): if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if oldThemeName == newThemeName: if old_theme_name == new_theme_name:
return return
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(new_theme_name):
oldThemeData = self.getThemeData(oldThemeName) old_theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(old_theme_data, new_theme_name)
self.deleteTheme(oldThemeName) self.deleteTheme(old_theme_name)
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName): if plugin.usesTheme(old_theme_name):
plugin.renameTheme(oldThemeName, newThemeName) plugin.renameTheme(old_theme_name, new_theme_name)
self.loadThemes() self.loadThemes()
def onCopyTheme(self): def onCopyTheme(self):
@ -289,30 +289,30 @@ class ThemeManager(QtGui.QWidget):
Copies an existing theme to a new name Copies an existing theme to a new name
""" """
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText( self.fileRenameForm.fileNameEdit.setText(
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Copy of %s','Copy of <theme name>')) % oldThemeName) 'Copy of %s', 'Copy of <theme name>')) % old_theme_name)
if self.fileRenameForm.exec_(True): if self.fileRenameForm.exec_(True):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(new_theme_name):
themeData = self.getThemeData(oldThemeName) theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(themeData, newThemeName) self.cloneThemeData(theme_data, new_theme_name)
def cloneThemeData(self, themeData, newThemeName): def cloneThemeData(self, theme_data, new_theme_name):
""" """
Takes a theme and makes a new copy of it as well as saving it. Takes a theme and makes a new copy of it as well as saving it.
""" """
log.debug(u'cloneThemeData') log.debug(u'cloneThemeData')
saveTo = None save_to = None
saveFrom = None save_from = None
if themeData.background_type == u'image': if theme_data.background_type == u'image':
saveTo = os.path.join(self.path, newThemeName, save_to = os.path.join(self.path, new_theme_name,
os.path.split(unicode(themeData.background_filename))[1]) os.path.split(unicode(theme_data.background_filename))[1])
saveFrom = themeData.background_filename save_from = theme_data.background_filename
themeData.theme_name = newThemeName theme_data.theme_name = new_theme_name
themeData.extend_image_filename(self.path) theme_data.extend_image_filename(self.path)
self.saveTheme(themeData, saveFrom, saveTo) self.saveTheme(theme_data, save_from, save_to)
def onEditTheme(self): def onEditTheme(self):
""" """
@ -326,10 +326,10 @@ class ThemeManager(QtGui.QWidget):
theme = self.getThemeData( theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image': if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename self.old_background_image = theme.background_filename
self.themeForm.theme = theme self.themeForm.theme = theme
self.themeForm.exec_(True) self.themeForm.exec_(True)
self.oldBackgroundImage = None self.old_background_image = None
def onDeleteTheme(self): def onDeleteTheme(self):
""" """
@ -355,10 +355,10 @@ class ThemeManager(QtGui.QWidget):
``theme`` ``theme``
The theme to delete. The theme to delete.
""" """
self.themelist.remove(theme) self.theme_list.remove(theme)
thumb = u'%s.png' % theme thumb = u'%s.png' % theme
delete_file(os.path.join(self.path, thumb)) delete_file(os.path.join(self.path, thumb))
delete_file(os.path.join(self.thumbPath, thumb)) delete_file(os.path.join(self.thumb_path, thumb))
try: try:
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
@ -383,10 +383,10 @@ class ThemeManager(QtGui.QWidget):
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
if path: if path:
SettingsManager.set_last_dir(self.settingsSection, path, 1) SettingsManager.set_last_dir(self.settingsSection, path, 1)
themePath = os.path.join(path, theme + u'.otz') theme_path = os.path.join(path, theme + u'.otz')
zip = None zip = None
try: try:
zip = zipfile.ZipFile(themePath, u'w') zip = zipfile.ZipFile(theme_path, u'w')
source = os.path.join(self.path, theme) source = os.path.join(self.path, theme)
for files in os.walk(source): for files in os.walk(source):
for name in files[2]: for name in files[2]:
@ -436,9 +436,8 @@ class ThemeManager(QtGui.QWidget):
The plugins will call back in to get the real list if they want it. The plugins will call back in to get the real list if they want it.
""" """
log.debug(u'Load themes from dir') log.debug(u'Load themes from dir')
self.themelist = [] self.theme_list = []
self.themeListWidget.clear() self.themeListWidget.clear()
dirList = os.listdir(self.path)
files = SettingsManager.get_files(self.settingsSection, u'.png') files = SettingsManager.get_files(self.settingsSection, u'.png')
if firstTime: if firstTime:
self.firstTime() self.firstTime()
@ -455,29 +454,29 @@ class ThemeManager(QtGui.QWidget):
files = SettingsManager.get_files(self.settingsSection, u'.png') files = SettingsManager.get_files(self.settingsSection, u'.png')
# Sort the themes by its name considering language specific characters. # Sort the themes by its name considering language specific characters.
# lower() is needed for windows! # lower() is needed for windows!
files.sort(key=lambda filename: unicode(filename).lower(), files.sort(key=lambda file_name: unicode(file_name).lower(),
cmp=locale.strcoll) cmp=locale.strcoll)
# now process the file list of png files # now process the file list of png files
for name in files: for name in files:
# check to see file is in theme root directory # check to see file is in theme root directory
theme = os.path.join(self.path, name) theme = os.path.join(self.path, name)
if os.path.exists(theme): if os.path.exists(theme):
textName = os.path.splitext(name)[0] text_name = os.path.splitext(name)[0]
if textName == self.global_theme: if text_name == self.global_theme:
name = unicode(translate('OpenLP.ThemeManager', name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % textName '%s (default)')) % text_name
else: else:
name = textName name = text_name
thumb = os.path.join(self.thumbPath, u'%s.png' % textName) thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
item_name = QtGui.QListWidgetItem(name) item_name = QtGui.QListWidgetItem(name)
if validate_thumb(theme, thumb): if validate_thumb(theme, thumb):
icon = build_icon(thumb) icon = build_icon(thumb)
else: else:
icon = create_thumb(theme, thumb) icon = create_thumb(theme, thumb)
item_name.setIcon(icon) item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(text_name))
self.themeListWidget.addItem(item_name) self.themeListWidget.addItem(item_name)
self.themelist.append(textName) self.theme_list.append(text_name)
self._pushThemes() self._pushThemes()
def _pushThemes(self): def _pushThemes(self):
@ -490,50 +489,68 @@ class ThemeManager(QtGui.QWidget):
""" """
Return the list of loaded themes Return the list of loaded themes
""" """
return self.themelist return self.theme_list
def getThemeData(self, themeName): def getThemeData(self, theme_name):
""" """
Returns a theme object from an XML file Returns a theme object from an XML file
``themeName`` ``theme_name``
Name of the theme to load from file Name of the theme to load from file
""" """
log.debug(u'getthemedata for theme %s', themeName) log.debug(u'getthemedata for theme %s', theme_name)
xmlFile = os.path.join(self.path, unicode(themeName), xml_file = os.path.join(self.path, unicode(theme_name),
unicode(themeName) + u'.xml') unicode(theme_name) + u'.xml')
xml = get_text_file_string(xmlFile) xml = get_text_file_string(xml_file)
if not xml: if not xml:
log.debug("No theme data - using default theme") log.debug("No theme data - using default theme")
return ThemeXML() return ThemeXML()
else: else:
return self._createThemeFromXml(xml, self.path) return self._createThemeFromXml(xml, self.path)
def unzipTheme(self, filename, dir): def overWriteMessageBox(self, theme_name):
ret = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?'
% theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
return ret == QtGui.QMessageBox.Yes
def unzipTheme(self, file_name, dir):
""" """
Unzip the theme, remove the preview file if stored Unzip the theme, remove the preview file if stored
Generate a new preview file. Check the XML theme version and upgrade if Generate a new preview file. Check the XML theme version and upgrade if
necessary. necessary.
""" """
log.debug(u'Unzipping theme %s', filename) log.debug(u'Unzipping theme %s', file_name)
filename = unicode(filename) file_name = unicode(file_name)
zip = None zip = None
outfile = None out_file = None
filexml = None file_xml = None
try: try:
zip = zipfile.ZipFile(filename) zip = zipfile.ZipFile(file_name)
xmlfile = filter(lambda name: xml_file = filter(lambda name:
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist()) os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
if len(xmlfile) != 1: if len(xml_file) != 1:
log.exception(u'Theme contains "%s" XML files' % len(xmlfile)) log.exception(u'Theme contains "%s" XML files' % len(xml_file))
raise Exception(u'validation') raise Exception(u'validation')
xml_tree = ElementTree(element=XML(zip.read(xmlfile[0]))).getroot() xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
v1_background = xml_tree.find(u'BackgroundType') v1_background = xml_tree.find(u'BackgroundType')
if v1_background is not None: if v1_background is not None:
(themename, filexml, outfile) = self.unzipVersion122(dir, zip, theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
xmlfile[0], xml_tree, v1_background, outfile) xml_file[0], xml_tree, v1_background, out_file)
else: else:
themename = xml_tree.find(u'name').text.strip() theme_name = xml_tree.find(u'name').text.strip()
theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
abort_import = True
return
else:
abort_import = False
for name in zip.namelist(): for name in zip.namelist():
try: try:
uname = unicode(name, u'utf-8') uname = unicode(name, u'utf-8')
@ -542,22 +559,22 @@ class ThemeManager(QtGui.QWidget):
u' "%s"' % name.decode(u'utf-8', u'replace')) u' "%s"' % name.decode(u'utf-8', u'replace'))
raise Exception(u'validation') raise Exception(u'validation')
uname = uname.replace(u'/', os.path.sep) uname = uname.replace(u'/', os.path.sep)
splitname = uname.split(os.path.sep) split_name = uname.split(os.path.sep)
if splitname[-1] == u'' or len(splitname) == 1: if split_name[-1] == u'' or len(split_name) == 1:
# is directory or preview file # is directory or preview file
continue continue
fullname = os.path.join(dir, uname) full_name = os.path.join(dir, uname)
check_directory_exists(os.path.dirname(fullname)) check_directory_exists(os.path.dirname(full_name))
if os.path.splitext(uname)[1].lower() == u'.xml': if os.path.splitext(uname)[1].lower() == u'.xml':
filexml = unicode(zip.read(name), u'utf-8') file_xml = unicode(zip.read(name), u'utf-8')
outfile = open(fullname, u'w') out_file = open(full_name, u'w')
outfile.write(filexml.encode(u'utf-8')) out_file.write(file_xml.encode(u'utf-8'))
else: else:
outfile = open(fullname, u'wb') out_file = open(full_name, u'wb')
outfile.write(zip.read(name)) out_file.write(zip.read(name))
outfile.close() out_file.close()
except (IOError, zipfile.BadZipfile): except (IOError, zipfile.BadZipfile):
log.exception(u'Importing theme from zip failed %s' % filename) log.exception(u'Importing theme from zip failed %s' % file_name)
raise Exception(u'validation') raise Exception(u'validation')
except Exception as info: except Exception as info:
if unicode(info) == u'validation': if unicode(info) == u'validation':
@ -570,60 +587,65 @@ class ThemeManager(QtGui.QWidget):
# Close the files, to be able to continue creating the theme. # Close the files, to be able to continue creating the theme.
if zip: if zip:
zip.close() zip.close()
if outfile: if out_file:
outfile.close() out_file.close()
# As all files are closed, we can create the Theme. if not abort_import:
if filexml: # As all files are closed, we can create the Theme.
theme = self._createThemeFromXml(filexml, self.path) if file_xml:
self.generateAndSaveImage(dir, themename, theme) theme = self._createThemeFromXml(file_xml, self.path)
# Only show the error message, when IOError was not raised (in this self.generateAndSaveImage(dir, theme_name, theme)
# case the error message has already been shown). # Only show the error message, when IOError was not raised (in this
elif zip is not None: # case the error message has already been shown).
critical_error_message_box( elif zip is not None:
translate('OpenLP.ThemeManager', 'Validation Error'), critical_error_message_box(
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager', 'Validation Error'),
'File is not a valid theme.')) translate('OpenLP.ThemeManager',
log.exception(u'Theme file does not contain XML data %s' % 'File is not a valid theme.'))
filename) log.exception(u'Theme file does not contain XML data %s' %
file_name)
def unzipVersion122(self, dir, zip, xmlfile, xml_tree, background, outfile): def unzipVersion122(self, dir, zip, xml_file, xml_tree, background, out_file):
""" """
Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
this method, please keep in mind, that some parameters are redundant. this method, please keep in mind, that some parameters are redundant.
""" """
themename = xml_tree.find(u'Name').text.strip() theme_name = xml_tree.find(u'Name').text.strip()
themename = self.bad_v1_name_chars.sub(u'', themename) theme_name = self.bad_v1_name_chars.sub(u'', theme_name)
themedir = os.path.join(dir, themename) theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
return '', '', '', True
themedir = os.path.join(dir, theme_name)
check_directory_exists(themedir) check_directory_exists(themedir)
filexml = unicode(zip.read(xmlfile), u'utf-8') file_xml = unicode(zip.read(xml_file), u'utf-8')
filexml = self._migrateVersion122(filexml) file_xml = self._migrateVersion122(file_xml)
outfile = open(os.path.join(themedir, themename + u'.xml'), u'w') out_file = open(os.path.join(themedir, theme_name + u'.xml'), u'w')
outfile.write(filexml.encode(u'utf-8')) out_file.write(file_xml.encode(u'utf-8'))
outfile.close() out_file.close()
if background.text.strip() == u'2': if background.text.strip() == u'2':
imagename = xml_tree.find(u'BackgroundParameter1').text.strip() image_name = xml_tree.find(u'BackgroundParameter1').text.strip()
# image file has same extension and is in subfolder # image file has same extension and is in subfolder
imagefile = filter(lambda name: os.path.splitext(name)[1].lower() imagefile = filter(lambda name: os.path.splitext(name)[1].lower()
== os.path.splitext(imagename)[1].lower() and name.find(r'/'), == os.path.splitext(image_name)[1].lower() and name.find(r'/'),
zip.namelist()) zip.namelist())
if len(imagefile) >= 1: if len(imagefile) >= 1:
outfile = open(os.path.join(themedir, imagename), u'wb') out_file = open(os.path.join(themedir, image_name), u'wb')
outfile.write(zip.read(imagefile[0])) out_file.write(zip.read(imagefile[0]))
outfile.close() out_file.close()
else: else:
log.exception(u'Theme file does not contain image file "%s"' % log.exception(u'Theme file does not contain image file "%s"' %
imagename.decode(u'utf-8', u'replace')) image_name.decode(u'utf-8', u'replace'))
raise Exception(u'validation') raise Exception(u'validation')
return (themename, filexml, outfile) return theme_name, file_xml, out_file, False
def checkIfThemeExists(self, themeName): def checkIfThemeExists(self, theme_name):
""" """
Check if theme already exists and displays error message Check if theme already exists and displays error message
``themeName`` ``theme_name``
Name of the Theme to test Name of the Theme to test
""" """
theme_dir = os.path.join(self.path, themeName) theme_dir = os.path.join(self.path, theme_name)
if os.path.exists(theme_dir): if os.path.exists(theme_dir):
critical_error_message_box( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
@ -632,12 +654,12 @@ class ThemeManager(QtGui.QWidget):
return False return False
return True return True
def saveTheme(self, theme, imageFrom, imageTo): def saveTheme(self, theme, image_from, image_to):
""" """
Called by thememaintenance Dialog to save the theme Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list and to trigger the reload of the theme list
""" """
self._writeTheme(theme, imageFrom, imageTo) self._writeTheme(theme, image_from, image_to)
if theme.background_type == \ if theme.background_type == \
BackgroundType.to_string(BackgroundType.Image): BackgroundType.to_string(BackgroundType.Image):
self.mainwindow.imageManager.update_image(theme.theme_name, self.mainwindow.imageManager.update_image(theme.theme_name,
@ -645,7 +667,7 @@ class ThemeManager(QtGui.QWidget):
self.mainwindow.imageManager.process_updates() self.mainwindow.imageManager.process_updates()
self.loadThemes() self.loadThemes()
def _writeTheme(self, theme, imageFrom, imageTo): def _writeTheme(self, theme, image_from, image_to):
""" """
Writes the theme to the disk and handles the background image if Writes the theme to the disk and handles the background image if
necessary necessary
@ -656,24 +678,24 @@ class ThemeManager(QtGui.QWidget):
theme_dir = os.path.join(self.path, name) theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir) check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + u'.xml') theme_file = os.path.join(theme_dir, name + u'.xml')
if self.oldBackgroundImage and \ if self.old_background_image and \
imageTo != self.oldBackgroundImage: image_to != self.old_background_image:
delete_file(self.oldBackgroundImage) delete_file(self.old_background_image)
outfile = None out_file = None
try: try:
outfile = open(theme_file, u'w') out_file = open(theme_file, u'w')
outfile.write(theme_pretty_xml) out_file.write(theme_pretty_xml)
except IOError: except IOError:
log.exception(u'Saving theme to file failed') log.exception(u'Saving theme to file failed')
finally: finally:
if outfile: if out_file:
outfile.close() out_file.close()
if imageFrom and imageFrom != imageTo: if image_from and image_from != image_to:
try: try:
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.copyfile( shutil.copyfile(
unicode(imageFrom).encode(encoding), unicode(image_from).encode(encoding),
unicode(imageTo).encode(encoding)) unicode(image_to).encode(encoding))
except IOError: except IOError:
log.exception(u'Failed to save theme image') log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme) self.generateAndSaveImage(self.path, name, theme)
@ -681,39 +703,39 @@ class ThemeManager(QtGui.QWidget):
def generateAndSaveImage(self, dir, name, theme): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name) log.debug(u'generateAndSaveImage %s %s', dir, name)
frame = self.generateImage(theme) frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png') sample_path_name = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname): if os.path.exists(sample_path_name):
os.unlink(samplepathname) os.unlink(sample_path_name)
frame.save(samplepathname, u'png') frame.save(sample_path_name, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name) thumb = os.path.join(self.thumb_path, u'%s.png' % name)
create_thumb(samplepathname, thumb, False) create_thumb(sample_path_name, thumb, False)
log.debug(u'Theme image written to %s', samplepathname) log.debug(u'Theme image written to %s', sample_path_name)
def updatePreviewImages(self): def updatePreviewImages(self):
""" """
Called to update the themes' preview images. Called to update the themes' preview images.
""" """
self.mainwindow.displayProgressBar(len(self.themelist)) self.mainwindow.displayProgressBar(len(self.theme_list))
for theme in self.themelist: for theme in self.theme_list:
self.mainwindow.incrementProgressBar() self.mainwindow.incrementProgressBar()
self.generateAndSaveImage( self.generateAndSaveImage(
self.path, theme, self.getThemeData(theme)) self.path, theme, self.getThemeData(theme))
self.mainwindow.finishedProgressBar() self.mainwindow.finishedProgressBar()
self.loadThemes() self.loadThemes()
def generateImage(self, themeData, forcePage=False): def generateImage(self, theme_data, forcePage=False):
""" """
Call the renderer to build a Sample Image Call the renderer to build a Sample Image
``themeData`` ``theme_data``
The theme to generated a preview for. The theme to generated a preview for.
``forcePage`` ``forcePage``
Flag to tell message lines per page need to be generated. Flag to tell message lines per page need to be generated.
""" """
log.debug(u'generateImage \n%s ', themeData) log.debug(u'generateImage \n%s ', theme_data)
return self.mainwindow.renderer.generate_preview( return self.mainwindow.renderer.generate_preview(
themeData, forcePage) theme_data, forcePage)
def getPreviewImage(self, theme): def getPreviewImage(self, theme):
""" """
@ -726,15 +748,15 @@ class ThemeManager(QtGui.QWidget):
image = os.path.join(self.path, theme + u'.png') image = os.path.join(self.path, theme + u'.png')
return image return image
def _createThemeFromXml(self, themeXml, path): def _createThemeFromXml(self, theme_xml, path):
""" """
Return a theme object using information parsed from XML Return a theme object using information parsed from XML
``themeXml`` ``theme_xml``
The XML data to load into the theme The XML data to load into the theme
""" """
theme = ThemeXML() theme = ThemeXML()
theme.parse(themeXml) theme.parse(theme_xml)
theme.extend_image_filename(path) theme.extend_image_filename(path)
return theme return theme
@ -789,53 +811,53 @@ class ThemeManager(QtGui.QWidget):
Version 1 theme to convert Version 1 theme to convert
""" """
theme = Theme(xml_data) theme = Theme(xml_data)
newtheme = ThemeXML() new_theme = ThemeXML()
newtheme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name) new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
if theme.BackgroundType == 0: if theme.BackgroundType == 0:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Solid) BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \ new_theme.background_color = \
unicode(theme.BackgroundParameter1.name()) unicode(theme.BackgroundParameter1.name())
elif theme.BackgroundType == 1: elif theme.BackgroundType == 1:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Gradient) BackgroundType.to_string(BackgroundType.Gradient)
newtheme.background_direction = \ new_theme.background_direction = \
BackgroundGradientType. \ BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal) to_string(BackgroundGradientType.Horizontal)
if theme.BackgroundParameter3.name() == 1: if theme.BackgroundParameter3.name() == 1:
newtheme.background_direction = \ new_theme.background_direction = \
BackgroundGradientType. \ BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal) to_string(BackgroundGradientType.Horizontal)
newtheme.background_start_color = \ new_theme.background_start_color = \
unicode(theme.BackgroundParameter1.name()) unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \ new_theme.background_end_color = \
unicode(theme.BackgroundParameter2.name()) unicode(theme.BackgroundParameter2.name())
elif theme.BackgroundType == 2: elif theme.BackgroundType == 2:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Image) BackgroundType.to_string(BackgroundType.Image)
newtheme.background_filename = unicode(theme.BackgroundParameter1) new_theme.background_filename = unicode(theme.BackgroundParameter1)
elif theme.BackgroundType == 3: elif theme.BackgroundType == 3:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Transparent) BackgroundType.to_string(BackgroundType.Transparent)
newtheme.font_main_name = theme.FontName new_theme.font_main_name = theme.FontName
newtheme.font_main_color = unicode(theme.FontColor.name()) new_theme.font_main_color = unicode(theme.FontColor.name())
newtheme.font_main_size = theme.FontProportion * 3 new_theme.font_main_size = theme.FontProportion * 3
newtheme.font_footer_name = theme.FontName new_theme.font_footer_name = theme.FontName
newtheme.font_footer_color = unicode(theme.FontColor.name()) new_theme.font_footer_color = unicode(theme.FontColor.name())
newtheme.font_main_shadow = False new_theme.font_main_shadow = False
if theme.Shadow == 1: if theme.Shadow == 1:
newtheme.font_main_shadow = True new_theme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name()) new_theme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1: if theme.Outline == 1:
newtheme.font_main_outline = True new_theme.font_main_outline = True
newtheme.font_main_outline_color = \ new_theme.font_main_outline_color = \
unicode(theme.OutlineColor.name()) unicode(theme.OutlineColor.name())
vAlignCorrection = VerticalType.Top vAlignCorrection = VerticalType.Top
if theme.VerticalAlign == 2: if theme.VerticalAlign == 2:
vAlignCorrection = VerticalType.Middle vAlignCorrection = VerticalType.Middle
elif theme.VerticalAlign == 1: elif theme.VerticalAlign == 1:
vAlignCorrection = VerticalType.Bottom vAlignCorrection = VerticalType.Bottom
newtheme.display_horizontal_align = theme.HorizontalAlign new_theme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection new_theme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml() return new_theme.extract_xml()