# Path: mu/interface/themes.py
# class Font:
#     """
#     Utility class that makes it easy to set font related values within the
#     editor.
#     """
# 
#     _DATABASE = None
# 
#     def __init__(
#         self, color="#181818", paper="#FEFEF7", bold=False, italic=False
#     ):
#         self.color = color
#         self.paper = paper
#         self.bold = bold
#         self.italic = italic
# 
#     @classmethod
#     def get_database(cls):
#         """
#         Create a font database and load the MU builtin fonts into it.
#         This is a cached classmethod so the font files aren't re-loaded
#         every time a font is refereced
#         """
#         if cls._DATABASE is None:
#             cls._DATABASE = QFontDatabase()
#             for variant in FONT_VARIANTS:
#                 filename = FONT_FILENAME_PATTERN.format(variant=variant)
#                 font_data = load_font_data(filename)
#                 cls._DATABASE.addApplicationFontFromData(font_data)
#         return cls._DATABASE
# 
#     def load(self, size=DEFAULT_FONT_SIZE):
#         """
#         Load the font from the font database, using the correct size and style
#         """
#         return Font.get_database().font(FONT_NAME, self.stylename, size)
# 
#     @property
#     def stylename(self):
#         """
#         Map the bold and italic boolean flags here to a relevant
#         font style name.
#         """
#         if self.bold:
#             if self.italic:
#                 return "Semibold Italic"
#             return "Semibold"
#         if self.italic:
#             return "Italic"
#         return "Regular"
# 
# class DayTheme(Theme):
#     """
#     Defines a Python related theme including the various font colours for
#     syntax highlighting.
# 
#     This is a light theme.
#     """
# 
#     FunctionMethodName = ClassName = Font(color="#0000a0")
#     UnclosedString = Font(paper="#FFDDDD")
#     Comment = CommentBlock = Font(color="gray")
#     Keyword = Font(color="#005050", bold=True)
#     SingleQuotedString = DoubleQuotedString = Font(color="#800000")
#     SingleQuotedFString = DoubleQuotedFString = Font(color="#800000")
#     TripleSingleQuotedString = TripleDoubleQuotedString = Font(color="#060")
#     TripleSingleQuotedFString = TripleDoubleQuotedFString = Font(color="#060")
#     Number = Font(color="#00008B")
#     Decorator = Font(color="#cc6600")
#     Default = Identifier = Font()
#     Operator = Font(color="#400040")
#     HighlightedIdentifier = Font(color="#0000a0")
#     Paper = QColor("#FEFEF7")
#     Caret = QColor("#181818")
#     Margin = QColor("#EEE")
#     IndicatorError = QColor("red")
#     IndicatorStyle = QColor("blue")
#     DebugStyle = QColor("#ffcc33")
#     IndicatorWordMatch = QColor("lightGrey")
#     BraceBackground = QColor("lightGrey")
#     BraceForeground = QColor("blue")
#     UnmatchedBraceBackground = QColor("#FFDDDD")
#     UnmatchedBraceForeground = QColor("black")
#     BreakpointMarker = QColor("#D80000")
#     # HTML
#     Tag = Keyword
#     UnknownTag = Tag
#     XMLTagEnd = Tag
#     XMLStart = Tag
#     XMLEnd = Tag
#     Attribute = ClassName
#     UnknownAttribute = Attribute
#     HTMLNumber = Number
#     HTMLDoubleQuotedString = DoubleQuotedString
#     HTMLSingleQuotedString = SingleQuotedString
#     OtherInTag = Default
#     HTMLComment = Comment
#     Entity = Operator
#     CDATA = Decorator
#     # CSS
#     ClassSelector = Tag
#     PseudoClass = ClassSelector
#     UnknownPseudoClass = ClassSelector
#     CSS1Property = (
#         CSS2Property
#     ) = CSS3Property = UnknownProperty = SingleQuotedString
#     Value = Number
#     IDSelector = Tag
#     Important = UnmatchedBraceBackground
#     AtRule = Decorator
#     MediaRule = Decorator
#     Variable = HighlightedIdentifier
# 
# Path: mu/logic.py
# NEWLINE = "\n"


import keyword
import os
import re
import logging
import os.path
from collections import defaultdict
from PyQt5.Qsci import (
    QsciScintilla,
    QsciLexerPython,
    QsciLexerHTML,
    QsciAPIs,
    QsciLexerCSS,
)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QApplication
from mu.interface.themes import Font, DayTheme
from mu.logic import NEWLINE
        # click handler to ignore clicks on this margin: self.connect_margin.
        self.setMarginWidth(4, 8)
        self.setMarginSensitivity(4, True)
        # Indicators
        self.setIndicatorDrawUnder(True)
        for type_ in self.check_indicators:
            self.indicatorDefine(
                self.SquiggleIndicator, self.check_indicators[type_]["id"]
            )
        for type_ in self.search_indicators:
            self.indicatorDefine(
                self.StraightBoxIndicator, self.search_indicators[type_]["id"]
            )
        self.indicatorDefine(self.FullBoxIndicator, self.DEBUG_INDICATOR)
        self.setAnnotationDisplay(self.AnnotationBoxed)
        self.selectionChanged.connect(self.selection_change_listener)
        self.set_zoom()

    def connect_margin(self, func):
        """
        Connect clicking the margin to the passed in handler function, via a
        filtering handler that ignores clicks on margin 4.
        """
        # Margin 4 motivation in self.configure comments.
        def func_ignoring_margin_4(margin, line, modifiers):
            if margin != 4:
                func(margin, line, modifiers)

        self.marginClicked.connect(func_ignoring_margin_4)


# Path: mu/interface/themes.py
# class Font:
#     """
#     Utility class that makes it easy to set font related values within the
#     editor.
#     """
# 
#     _DATABASE = None
# 
#     def __init__(
#         self, color="#181818", paper="#FEFEF7", bold=False, italic=False
#     ):
#         self.color = color
#         self.paper = paper
#         self.bold = bold
#         self.italic = italic
# 
#     @classmethod
#     def get_database(cls):
#         """
#         Create a font database and load the MU builtin fonts into it.
#         This is a cached classmethod so the font files aren't re-loaded
#         every time a font is refereced
#         """
#         if cls._DATABASE is None:
#             cls._DATABASE = QFontDatabase()
#             for variant in FONT_VARIANTS:
#                 filename = FONT_FILENAME_PATTERN.format(variant=variant)
#                 font_data = load_font_data(filename)
#                 cls._DATABASE.addApplicationFontFromData(font_data)
#         return cls._DATABASE
# 
#     def load(self, size=DEFAULT_FONT_SIZE):
#         """
#         Load the font from the font database, using the correct size and style
#         """
#         return Font.get_database().font(FONT_NAME, self.stylename, size)
# 
#     @property
#     def stylename(self):
#         """
#         Map the bold and italic boolean flags here to a relevant
#         font style name.
#         """
#         if self.bold:
#             if self.italic:
#                 return "Semibold Italic"
#             return "Semibold"
#         if self.italic:
#             return "Italic"
#         return "Regular"
# 
# class DayTheme(Theme):
#     """
#     Defines a Python related theme including the various font colours for
#     syntax highlighting.
# 
#     This is a light theme.
#     """
# 
#     FunctionMethodName = ClassName = Font(color="#0000a0")
#     UnclosedString = Font(paper="#FFDDDD")
#     Comment = CommentBlock = Font(color="gray")
#     Keyword = Font(color="#005050", bold=True)
#     SingleQuotedString = DoubleQuotedString = Font(color="#800000")
#     SingleQuotedFString = DoubleQuotedFString = Font(color="#800000")
#     TripleSingleQuotedString = TripleDoubleQuotedString = Font(color="#060")
#     TripleSingleQuotedFString = TripleDoubleQuotedFString = Font(color="#060")
#     Number = Font(color="#00008B")
#     Decorator = Font(color="#cc6600")
#     Default = Identifier = Font()
#     Operator = Font(color="#400040")
#     HighlightedIdentifier = Font(color="#0000a0")
#     Paper = QColor("#FEFEF7")
#     Caret = QColor("#181818")
#     Margin = QColor("#EEE")
#     IndicatorError = QColor("red")
#     IndicatorStyle = QColor("blue")
#     DebugStyle = QColor("#ffcc33")
#     IndicatorWordMatch = QColor("lightGrey")
#     BraceBackground = QColor("lightGrey")
#     BraceForeground = QColor("blue")
#     UnmatchedBraceBackground = QColor("#FFDDDD")
#     UnmatchedBraceForeground = QColor("black")
#     BreakpointMarker = QColor("#D80000")
#     # HTML
#     Tag = Keyword
#     UnknownTag = Tag
#     XMLTagEnd = Tag
#     XMLStart = Tag
#     XMLEnd = Tag
#     Attribute = ClassName
#     UnknownAttribute = Attribute
#     HTMLNumber = Number
#     HTMLDoubleQuotedString = DoubleQuotedString
#     HTMLSingleQuotedString = SingleQuotedString
#     OtherInTag = Default
#     HTMLComment = Comment
#     Entity = Operator
#     CDATA = Decorator
#     # CSS
#     ClassSelector = Tag
#     PseudoClass = ClassSelector
#     UnknownPseudoClass = ClassSelector
#     CSS1Property = (
#         CSS2Property
#     ) = CSS3Property = UnknownProperty = SingleQuotedString
#     Value = Number
#     IDSelector = Tag
#     Important = UnmatchedBraceBackground
#     AtRule = Decorator
#     MediaRule = Decorator
#     Variable = HighlightedIdentifier
# 
# Path: mu/logic.py
# NEWLINE = "\n"


# Path: mu/interface/editor.py
import keyword
import os
import re
import logging
import os.path
from collections import defaultdict
from PyQt5.Qsci import (
    QsciScintilla,
    QsciLexerPython,
    QsciLexerHTML,
    QsciAPIs,
    QsciLexerCSS,
)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QApplication
from mu.interface.themes import Font, DayTheme
from mu.logic import NEWLINE

        # click handler to ignore clicks on this margin: self.connect_margin.
        self.setMarginWidth(4, 8)
        self.setMarginSensitivity(4, True)
        # Indicators
        self.setIndicatorDrawUnder(True)
        for type_ in self.check_indicators:
            self.indicatorDefine(
                self.SquiggleIndicator, self.check_indicators[type_]["id"]
            )
        for type_ in self.search_indicators:
            self.indicatorDefine(
                self.StraightBoxIndicator, self.search_indicators[type_]["id"]
            )
        self.indicatorDefine(self.FullBoxIndicator, self.DEBUG_INDICATOR)
        self.setAnnotationDisplay(self.AnnotationBoxed)
        self.selectionChanged.connect(self.selection_change_listener)
        self.set_zoom()

    def connect_margin(self, func):
        """
        Connect clicking the margin to the passed in handler function, via a
        filtering handler that ignores clicks on margin 4.
        """
        # Margin 4 motivation in self.configure comments.
        def func_ignoring_margin_4(margin, line, modifiers):
            if margin != 4:
                func(margin, line, modifiers)

        self.marginClicked.connect(func_ignoring_margin_4)


    def set_theme(self, theme=DayTheme):