~ubuntu-branches/debian/stretch/openlp/stretch

« back to all changes in this revision

Viewing changes to openlp/core/ui/thememanager.py

  • Committer: Package Import Robot
  • Author(s): Raoul Snyman
  • Date: 2014-02-04 20:37:41 UTC
  • mfrom: (1.2.1) (3.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20140204203741-dydzq1h14rak8ksz
Tags: 2.0.4-1
* New upstream release
* Update build-depends to debhelper 8
* Change maintainer e-mail

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
###############################################################################
5
5
# OpenLP - Open Source Lyrics Projection                                      #
6
6
# --------------------------------------------------------------------------- #
7
 
# Copyright (c) 2008-2012 Raoul Snyman                                        #
8
 
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan      #
 
7
# Copyright (c) 2008-2014 Raoul Snyman                                        #
 
8
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan      #
9
9
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub,      #
10
 
# Meinert Jordan, Armin Köhler, Edwin Lunando, Joshua Miller, Stevan Pettit,  #
11
 
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
12
 
# Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon      #
13
 
# Tibble, Dave Warnock, Frode Woldsund                                        #
 
10
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer.   #
 
11
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru,          #
 
12
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,             #
 
13
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock,              #
 
14
# Frode Woldsund, Martin Zibricky                                             #
14
15
# --------------------------------------------------------------------------- #
15
16
# This program is free software; you can redistribute it and/or modify it     #
16
17
# under the terms of the GNU General Public License as published by the Free  #
30
31
import zipfile
31
32
import shutil
32
33
import logging
33
 
import locale
34
34
import re
35
35
 
36
36
from xml.etree.ElementTree import ElementTree, XML
37
37
from PyQt4 import QtCore, QtGui
38
38
 
39
 
from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \
 
39
from openlp.core.lib import FileDialog, OpenLPToolbar, get_text_file_string, build_icon, \
40
40
    Receiver, SettingsManager, translate, check_item_selected, \
41
 
    check_directory_exists, create_thumb, validate_thumb
 
41
    check_directory_exists, create_thumb, validate_thumb, ImageSource
42
42
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
43
43
    BackgroundGradientType
44
44
from openlp.core.lib.settings import Settings
46
46
    create_widget_action
47
47
from openlp.core.theme import Theme
48
48
from openlp.core.ui import FileRenameForm, ThemeForm
49
 
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
 
49
from openlp.core.utils import AppLocation, delete_file, locale_compare, \
 
50
    get_filesystem_encoding
50
51
 
51
52
log = logging.getLogger(__name__)
52
53
 
139
140
        QtCore.QObject.connect(Receiver.get_receiver(),
140
141
            QtCore.SIGNAL(u'config_updated'), self.configUpdated)
141
142
        # Variables
142
 
        self.theme_list = []
 
143
        self.themeList = []
143
144
        self.path = AppLocation.get_section_data_path(self.settingsSection)
144
145
        check_directory_exists(self.path)
145
 
        self.thumb_path = os.path.join(self.path, u'thumbnails')
146
 
        check_directory_exists(self.thumb_path)
 
146
        self.thumbPath = os.path.join(self.path, u'thumbnails')
 
147
        check_directory_exists(self.thumbPath)
147
148
        self.themeForm.path = self.path
148
 
        self.old_background_image = None
149
 
        self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
 
149
        self.oldBackgroundImage = None
 
150
        self.badV1NameChars = re.compile(r'[%+\[\]]')
150
151
        # Last little bits of setting up
151
152
        self.configUpdated()
152
153
 
194
195
            return
195
196
        real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
196
197
        theme_name = unicode(item.text())
197
 
        self.deleteAction.setVisible(False)
198
 
        self.renameAction.setVisible(False)
199
 
        self.globalAction.setVisible(False)
200
 
        # If default theme restrict actions
201
 
        if real_theme_name == theme_name:
202
 
            self.deleteAction.setVisible(True)
203
 
            self.renameAction.setVisible(True)
204
 
            self.globalAction.setVisible(True)
 
198
        visible = real_theme_name == theme_name
 
199
        self.deleteAction.setVisible(visible)
 
200
        self.renameAction.setVisible(visible)
 
201
        self.globalAction.setVisible(visible)
205
202
        self.menu.exec_(self.themeListWidget.mapToGlobal(point))
206
203
 
207
204
    def changeGlobalFromTab(self, theme_name):
261
258
        theme.set_default_header_footer()
262
259
        self.themeForm.theme = theme
263
260
        self.themeForm.exec_()
 
261
        self.loadThemes()
264
262
 
265
263
    def onRenameTheme(self):
266
264
        """
285
283
                    for plugin in self.mainwindow.pluginManager.plugins:
286
284
                        if plugin.usesTheme(old_theme_name):
287
285
                            plugin.renameTheme(old_theme_name, new_theme_name)
288
 
                    self.loadThemes()
289
286
                    self.mainwindow.renderer.update_theme(
290
287
                        new_theme_name, old_theme_name)
 
288
                    self.loadThemes()
291
289
 
292
290
    def onCopyTheme(self):
293
291
        """
318
316
        theme_data.theme_name = new_theme_name
319
317
        theme_data.extend_image_filename(self.path)
320
318
        self.saveTheme(theme_data, save_from, save_to)
 
319
        self.loadThemes()
321
320
 
322
321
    def onEditTheme(self):
323
322
        """
330
329
            theme = self.getThemeData(
331
330
                unicode(item.data(QtCore.Qt.UserRole).toString()))
332
331
            if theme.background_type == u'image':
333
 
                self.old_background_image = theme.background_filename
 
332
                self.oldBackgroundImage = theme.background_filename
334
333
            self.themeForm.theme = theme
335
334
            self.themeForm.exec_(True)
336
 
            self.old_background_image = None
 
335
            self.oldBackgroundImage = None
337
336
            self.mainwindow.renderer.update_theme(theme.theme_name)
 
337
            self.loadThemes()
338
338
 
339
339
    def onDeleteTheme(self):
340
340
        """
349
349
            row = self.themeListWidget.row(item)
350
350
            self.themeListWidget.takeItem(row)
351
351
            self.deleteTheme(theme)
 
352
            self.mainwindow.renderer.update_theme(theme, only_delete=True)
352
353
            # As we do not reload the themes, push out the change. Reload the
353
354
            # list as the internal lists and events need to be triggered.
354
355
            self._pushThemes()
355
 
            self.mainwindow.renderer.update_theme(theme, only_delete=True)
356
356
 
357
357
    def deleteTheme(self, theme):
358
358
        """
361
361
        ``theme``
362
362
            The theme to delete.
363
363
        """
364
 
        self.theme_list.remove(theme)
 
364
        self.themeList.remove(theme)
365
365
        thumb = u'%s.png' % theme
366
366
        delete_file(os.path.join(self.path, thumb))
367
 
        delete_file(os.path.join(self.thumb_path, thumb))
 
367
        delete_file(os.path.join(self.thumbPath, thumb))
368
368
        try:
369
369
            encoding = get_filesystem_encoding()
370
370
            shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
420
420
        attempting to extract OpenLP themes from those files. This process
421
421
        will load both OpenLP version 1 and version 2 themes.
422
422
        """
423
 
        files = QtGui.QFileDialog.getOpenFileNames(self,
 
423
        files = FileDialog.getOpenFileNames(self,
424
424
            translate('OpenLP.ThemeManager', 'Select Theme Import File'),
425
425
            SettingsManager.get_last_dir(self.settingsSection),
426
426
            unicode(translate('OpenLP.ThemeManager',
442
442
        The plugins will call back in to get the real list if they want it.
443
443
        """
444
444
        log.debug(u'Load themes from dir')
445
 
        self.theme_list = []
 
445
        self.themeList = []
446
446
        self.themeListWidget.clear()
447
447
        files = SettingsManager.get_files(self.settingsSection, u'.png')
448
448
        if firstTime:
459
459
                self.configUpdated()
460
460
                files = SettingsManager.get_files(self.settingsSection, u'.png')
461
461
        # Sort the themes by its name considering language specific characters.
462
 
        # lower() is needed for windows!
463
 
        files.sort(key=lambda file_name: unicode(file_name).lower(),
464
 
           cmp=locale.strcoll)
 
462
        files.sort(key=lambda file_name: unicode(file_name),
 
463
           cmp=locale_compare)
465
464
        # now process the file list of png files
466
465
        for name in files:
467
466
            # check to see file is in theme root directory
473
472
                        '%s (default)')) % text_name
474
473
                else:
475
474
                    name = text_name
476
 
                thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
 
475
                thumb = os.path.join(self.thumbPath, u'%s.png' % text_name)
477
476
                item_name = QtGui.QListWidgetItem(name)
478
477
                if validate_thumb(theme, thumb):
479
478
                    icon = build_icon(thumb)
480
479
                else:
481
480
                    icon = create_thumb(theme, thumb)
482
481
                item_name.setIcon(icon)
483
 
                item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(text_name))
 
482
                item_name.setData(
 
483
                    QtCore.Qt.UserRole, QtCore.QVariant(text_name))
484
484
                self.themeListWidget.addItem(item_name)
485
 
                self.theme_list.append(text_name)
 
485
                self.themeList.append(text_name)
486
486
        self._pushThemes()
487
487
 
488
488
    def _pushThemes(self):
495
495
        """
496
496
        Return the list of loaded themes
497
497
        """
498
 
        return self.theme_list
 
498
        return self.themeList
499
499
 
500
500
    def getThemeData(self, theme_name):
501
501
        """
509
509
            unicode(theme_name) + u'.xml')
510
510
        xml = get_text_file_string(xml_file)
511
511
        if not xml:
512
 
            log.debug("No theme data - using default theme")
 
512
            log.debug(u'No theme data - using default theme')
513
513
            return ThemeXML()
514
514
        else:
515
515
            return self._createThemeFromXml(xml, self.path)
519
519
            translate('OpenLP.ThemeManager', 'Theme Already Exists'),
520
520
            translate('OpenLP.ThemeManager',
521
521
                'Theme %s already exists. Do you want to replace it?'
522
 
                % theme_name),
 
522
                ).replace('%s', theme_name),
523
523
            QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
524
524
                QtGui.QMessageBox.No),
525
525
            QtGui.QMessageBox.No)
547
547
            xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
548
548
            v1_background = xml_tree.find(u'BackgroundType')
549
549
            if v1_background is not None:
550
 
                theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
551
 
                    xml_file[0], xml_tree, v1_background, out_file)
 
550
                theme_name, file_xml, out_file, abort_import = \
 
551
                    self.unzipVersion122(
 
552
                    dir, zip, xml_file[0], xml_tree, v1_background, out_file)
552
553
            else:
553
554
                theme_name = xml_tree.find(u'name').text.strip()
554
555
                theme_folder = os.path.join(dir, theme_name)
601
602
                if file_xml:
602
603
                    theme = self._createThemeFromXml(file_xml, self.path)
603
604
                    self.generateAndSaveImage(dir, theme_name, theme)
604
 
                # Only show the error message, when IOError was not raised (in this
605
 
                # case the error message has already been shown).
 
605
                # Only show the error message, when IOError was not raised (in
 
606
                # this case the error message has already been shown).
606
607
                elif zip is not None:
607
608
                    critical_error_message_box(
608
609
                        translate('OpenLP.ThemeManager', 'Validation Error'),
611
612
                    log.exception(u'Theme file does not contain XML data %s' %
612
613
                        file_name)
613
614
 
614
 
    def unzipVersion122(self, dir, zip, xml_file, xml_tree, background, out_file):
 
615
    def unzipVersion122(self, dir, zip, xml_file, xml_tree, background,
 
616
        out_file):
615
617
        """
616
618
        Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
617
619
        this method, please keep in mind, that some parameters are redundant.
618
620
        """
619
621
        theme_name = xml_tree.find(u'Name').text.strip()
620
 
        theme_name = self.bad_v1_name_chars.sub(u'', theme_name)
 
622
        theme_name = self.badV1NameChars.sub(u'', theme_name)
621
623
        theme_folder = os.path.join(dir, theme_name)
622
624
        theme_exists = os.path.exists(theme_folder)
623
625
        if theme_exists and not self.overWriteMessageBox(theme_name):
632
634
        if background.text.strip() == u'2':
633
635
            image_name = xml_tree.find(u'BackgroundParameter1').text.strip()
634
636
            # image file has same extension and is in subfolder
635
 
            imagefile = filter(lambda name: os.path.splitext(name)[1].lower()
 
637
            image_file = filter(lambda name: os.path.splitext(name)[1].lower()
636
638
                == os.path.splitext(image_name)[1].lower() and name.find(r'/'),
637
639
                zip.namelist())
638
 
            if len(imagefile) >= 1:
 
640
            if len(image_file) >= 1:
639
641
                out_file = open(os.path.join(themedir, image_name), u'wb')
640
 
                out_file.write(zip.read(imagefile[0]))
 
642
                out_file.write(zip.read(image_file[0]))
641
643
                out_file.close()
642
644
            else:
643
645
                log.exception(u'Theme file does not contain image file "%s"' %
669
671
        self._writeTheme(theme, image_from, image_to)
670
672
        if theme.background_type == \
671
673
            BackgroundType.to_string(BackgroundType.Image):
672
 
            self.mainwindow.imageManager.updateImage(theme.theme_name,
673
 
                u'theme', QtGui.QColor(theme.background_border_color))
 
674
            self.mainwindow.imageManager.updateImageBorder(
 
675
                theme.background_filename,
 
676
                ImageSource.Theme, QtGui.QColor(theme.background_border_color))
674
677
            self.mainwindow.imageManager.processUpdates()
675
 
        self.loadThemes()
676
678
 
677
679
    def _writeTheme(self, theme, image_from, image_to):
678
680
        """
685
687
        theme_dir = os.path.join(self.path, name)
686
688
        check_directory_exists(theme_dir)
687
689
        theme_file = os.path.join(theme_dir, name + u'.xml')
688
 
        if self.old_background_image and \
689
 
            image_to != self.old_background_image:
690
 
            delete_file(self.old_background_image)
 
690
        if self.oldBackgroundImage and image_to != self.oldBackgroundImage:
 
691
            delete_file(self.oldBackgroundImage)
691
692
        out_file = None
692
693
        try:
693
694
            out_file = open(theme_file, u'w')
714
715
        if os.path.exists(sample_path_name):
715
716
            os.unlink(sample_path_name)
716
717
        frame.save(sample_path_name, u'png')
717
 
        thumb = os.path.join(self.thumb_path, u'%s.png' % name)
 
718
        thumb = os.path.join(self.thumbPath, u'%s.png' % name)
718
719
        create_thumb(sample_path_name, thumb, False)
719
720
        log.debug(u'Theme image written to %s', sample_path_name)
720
721
 
722
723
        """
723
724
        Called to update the themes' preview images.
724
725
        """
725
 
        self.mainwindow.displayProgressBar(len(self.theme_list))
726
 
        for theme in self.theme_list:
 
726
        self.mainwindow.displayProgressBar(len(self.themeList))
 
727
        for theme in self.themeList:
727
728
            self.mainwindow.incrementProgressBar()
728
729
            self.generateAndSaveImage(
729
730
                self.path, theme, self.getThemeData(theme))
819
820
        """
820
821
        theme = Theme(xml_data)
821
822
        new_theme = ThemeXML()
822
 
        new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
 
823
        new_theme.theme_name = self.badV1NameChars.sub(u'', theme.Name)
823
824
        if theme.BackgroundType == 0:
824
825
            new_theme.background_type = \
825
826
                BackgroundType.to_string(BackgroundType.Solid)