~trb143/openlp/more_media

« back to all changes in this revision

Viewing changes to openlp/core/display/render.py

  • Committer: Tim Bentley
  • Date: 2019-06-11 18:08:21 UTC
  • mfrom: (2876.1.2 openlp)
  • Revision ID: tim.bentley@gmail.com-20190611180821-m0viu2wi93p2o97k
Head

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
"""
25
25
import html
26
26
import logging
 
27
import mako
27
28
import math
28
29
import os
29
30
import re
32
33
from PyQt5 import QtWidgets, QtGui
33
34
 
34
35
from openlp.core.common import ThemeLevel
 
36
from openlp.core.common.i18n import translate
35
37
from openlp.core.common.mixins import LogMixin, RegistryProperties
36
38
from openlp.core.common.registry import Registry, RegistryBase
 
39
from openlp.core.common.settings import Settings
37
40
from openlp.core.display.screens import ScreenList
38
41
from openlp.core.display.window import DisplayWindow
39
42
from openlp.core.lib import ItemCapabilities
58
61
    '{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
59
62
    'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
60
63
VERSE_FOR_LINE_COUNT = '\n'.join(map(str, range(100)))
61
 
TITLE = 'Arky Arky (Unknown)'
62
 
FOOTER = ['Public Domain', 'CCLI 123456']
 
64
TITLE = 'Arky Arky'
 
65
AUTHOR = 'John Doe'
 
66
FOOTER_COPYRIGHT = 'Public Domain'
 
67
CCLI_NO = '123456'
63
68
 
64
69
 
65
70
def remove_tags(text, can_remove_chords=False):
425
430
    return raw_text + ''.join(end_tags), ''.join(start_tags), ''.join(html_tags)
426
431
 
427
432
 
428
 
class Renderer(RegistryBase, LogMixin, RegistryProperties, DisplayWindow):
 
433
class ThemePreviewRenderer(LogMixin, DisplayWindow):
429
434
    """
430
435
    A virtual display used for rendering thumbnails and other offscreen tasks
431
436
    """
435
440
        """
436
441
        super().__init__(*args, **kwargs)
437
442
        self.force_page = False
438
 
        for screen in ScreenList():
439
 
            if screen.is_display:
440
 
                self.setGeometry(screen.display_geometry.x(), screen.display_geometry.y(),
441
 
                                 screen.display_geometry.width(), screen.display_geometry.height())
442
 
                break
443
 
        # If the display is not show'ed and hidden like this webegine will not render
444
 
        self.show()
445
 
        self.hide()
446
 
        self.theme_height = 0
447
 
        self.theme_level = ThemeLevel.Global
448
 
 
449
 
    def set_theme_level(self, theme_level):
450
 
        """
451
 
        Sets the theme level.
452
 
 
453
 
        :param theme_level: The theme level to be used.
454
 
        """
455
 
        self.theme_level = theme_level
456
443
 
457
444
    def calculate_line_count(self):
458
445
        """
466
453
        """
467
454
        return self.run_javascript('Display.clearSlides();')
468
455
 
469
 
    def generate_preview(self, theme_data, force_page=False):
 
456
    def generate_footer(self):
 
457
        """
 
458
        """
 
459
        footer_template = Settings().value('songs/footer template')
 
460
        # Keep this in sync with the list in songstab.py
 
461
        vars = {
 
462
            'title': TITLE,
 
463
            'authors_none_label': translate('OpenLP.Ui', 'Written by'),
 
464
            'authors_words_label': translate('SongsPlugin.AuthorType', 'Words',
 
465
                                             'Author who wrote the lyrics of a song'),
 
466
            'authors_words': [AUTHOR],
 
467
            'copyright': FOOTER_COPYRIGHT,
 
468
            'ccli_license': Settings().value('core/ccli number'),
 
469
            'ccli_license_label': translate('SongsPlugin.MediaItem', 'CCLI License'),
 
470
            'ccli_number': CCLI_NO,
 
471
        }
 
472
        try:
 
473
            footer_html = mako.template.Template(footer_template).render_unicode(**vars).replace('\n', '')
 
474
        except mako.exceptions.SyntaxException:
 
475
            log.error('Failed to render Song footer html:\n' + mako.exceptions.text_error_template().render())
 
476
            footer_html = 'Dummy footer text'
 
477
        return footer_html
 
478
 
 
479
    def generate_preview(self, theme_data, force_page=False, generate_screenshot=True):
470
480
        """
471
481
        Generate a preview of a theme.
472
482
 
479
489
        if not self.force_page:
480
490
            self.set_theme(theme_data)
481
491
            self.theme_height = theme_data.font_main_height
482
 
            slides = self.format_slide(render_tags(VERSE), None)
 
492
            slides = self.format_slide(VERSE, None)
483
493
            verses = dict()
484
494
            verses['title'] = TITLE
485
 
            verses['text'] = slides[0]
 
495
            verses['text'] = render_tags(slides[0])
486
496
            verses['verse'] = 'V1'
 
497
            verses['footer'] = self.generate_footer()
487
498
            self.load_verses([verses])
488
499
            self.force_page = False
489
 
            return self.save_screenshot()
 
500
            if generate_screenshot:
 
501
                return self.save_screenshot()
490
502
        self.force_page = False
491
503
        return None
492
504
 
515
527
        if item and item.is_capable(ItemCapabilities.CanWordSplit):
516
528
            pages = self._paginate_slide_words(text.split('\n'), line_end)
517
529
        # Songs and Custom
518
 
        elif item is None or item.is_capable(ItemCapabilities.CanSoftBreak):
 
530
        elif item is None or (item and item.is_capable(ItemCapabilities.CanSoftBreak)):
519
531
            pages = []
520
532
            if '[---]' in text:
521
533
                # Remove Overflow split if at start of the text
722
734
        :param text:  The text to check. It may contain HTML tags.
723
735
        """
724
736
        self.clear_slides()
725
 
        self.run_javascript('Display.addTextSlide("v1", "{text}", "Dummy Footer");'.format(text=text), is_sync=True)
 
737
        self.run_javascript('Display.addTextSlide("v1", "{text}", "Dummy Footer");'
 
738
                            .format(text=text.replace('"', '\\"')), is_sync=True)
726
739
        does_text_fits = self.run_javascript('Display.doesContentFit();', is_sync=True)
727
740
        return does_text_fits
728
741
 
745
758
            pixmap.save(fname, ext)
746
759
        else:
747
760
            return pixmap
 
761
 
 
762
 
 
763
class Renderer(RegistryBase, RegistryProperties, ThemePreviewRenderer):
 
764
    """
 
765
    A virtual display used for rendering thumbnails and other offscreen tasks
 
766
    """
 
767
    def __init__(self, *args, **kwargs):
 
768
        """
 
769
        Constructor
 
770
        """
 
771
        super().__init__(*args, **kwargs)
 
772
        self.force_page = False
 
773
        for screen in ScreenList():
 
774
            if screen.is_display:
 
775
                self.setGeometry(screen.display_geometry.x(), screen.display_geometry.y(),
 
776
                                 screen.display_geometry.width(), screen.display_geometry.height())
 
777
                break
 
778
        # If the display is not show'ed and hidden like this webegine will not render
 
779
        self.show()
 
780
        self.hide()
 
781
        self.theme_height = 0
 
782
        self.theme_level = ThemeLevel.Global
 
783
 
 
784
    def set_theme_level(self, theme_level):
 
785
        """
 
786
        Sets the theme level.
 
787
 
 
788
        :param theme_level: The theme level to be used.
 
789
        """
 
790
        self.theme_level = theme_level