1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing the Diff colours configuration page.
8"""
9
10from PyQt5.QtCore import pyqtSlot
11from PyQt5.QtGui import QPalette
12from PyQt5.QtWidgets import QColorDialog
13
14from .ConfigurationPageBase import ConfigurationPageBase
15from .Ui_DiffColoursPage import Ui_DiffColoursPage
16
17import Preferences
18
19
20class DiffColoursPage(ConfigurationPageBase, Ui_DiffColoursPage):
21    """
22    Class implementing the Diff colours configuration page.
23    """
24    def __init__(self):
25        """
26        Constructor
27        """
28        super().__init__()
29        self.setupUi(self)
30        self.setObjectName("DiffColoursPage")
31
32        self.__coloursDict = {}
33
34        monospacedFont = Preferences.getEditorOtherFonts("MonospacedFont")
35        self.__allSamples = (
36            self.textSample, self.addedSample, self.removedSample,
37            self.replacedSample, self.contextSample, self.headerSample,
38            self.whitespaceSample)
39        for sample in self.__allSamples:
40            sample.setFont(monospacedFont)
41
42        # set initial values
43        self.__initColour(
44            "TextColor",
45            self.textButton,
46            self.__updateSampleTextColour,
47            lambda: self.__selectTextColour(self.textButton),
48            self.textSample)
49        self.__initColour(
50            "AddedColor",
51            self.addedButton,
52            self.__updateSampleBackgroundColour,
53            lambda: self.__selectBackgroundColour(self.addedButton),
54            self.addedSample)
55        self.__initColour(
56            "RemovedColor",
57            self.removedButton,
58            self.__updateSampleBackgroundColour,
59            lambda: self.__selectBackgroundColour(self.removedButton),
60            self.removedSample)
61        self.__initColour(
62            "ReplacedColor",
63            self.replacedButton,
64            self.__updateSampleBackgroundColour,
65            lambda: self.__selectBackgroundColour(self.replacedButton),
66            self.replacedSample)
67        self.__initColour(
68            "ContextColor",
69            self.contextButton,
70            self.__updateSampleBackgroundColour,
71            lambda: self.__selectBackgroundColour(self.contextButton),
72            self.contextSample)
73        self.__initColour(
74            "HeaderColor",
75            self.headerButton,
76            self.__updateSampleBackgroundColour,
77            lambda: self.__selectBackgroundColour(self.headerButton),
78            self.headerSample)
79        self.__initColour(
80            "BadWhitespaceColor",
81            self.whitespaceButton,
82            self.__updateSampleBackgroundColour,
83            lambda: self.__selectBackgroundColour(self.whitespaceButton),
84            self.whitespaceSample)
85
86    def save(self):
87        """
88        Public slot to save the Diff colours configuration.
89        """
90        for key in self.__coloursDict:
91            Preferences.setDiffColour(key, self.__coloursDict[key][0])
92
93    def __initColour(self, colourKey, button, initSlot, selectSlot,
94                     sampleWidget):
95        """
96        Private method to initialize a colour selection button.
97
98        @param colourKey key of the diff colour
99        @type str
100        @param button reference to the button
101        @type QPushButton
102        @param initSlot slot to be called to initialize the sample
103        @type func
104        @param selectSlot slot to be called to select the colour
105        @type func
106        @param sampleWidget reference to the sample widget
107        @type QLineEdit
108        """
109        colour = Preferences.getDiffColour(colourKey)
110        button.setProperty("colorKey", colourKey)
111        button.clicked.connect(selectSlot)
112        self.__coloursDict[colourKey] = [colour, sampleWidget]
113        if initSlot:
114            initSlot(colourKey)
115
116    @pyqtSlot()
117    def __selectTextColour(self, button):
118        """
119        Private slot to select the text colour.
120
121        @param button reference to the button been pressed
122        @type QPushButton
123        """
124        colorKey = button.property("colorKey")
125
126        colour = QColorDialog.getColor(self.__coloursDict[colorKey][0], self)
127        if colour.isValid():
128            self.__coloursDict[colorKey][0] = colour
129            self.__updateSampleTextColour(colorKey)
130
131    @pyqtSlot()
132    def __selectBackgroundColour(self, button):
133        """
134        Private slot to select a background colour.
135
136        @param button reference to the button been pressed
137        @type QPushButton
138        """
139        colorKey = button.property("colorKey")
140
141        colour = QColorDialog.getColor(
142            self.__coloursDict[colorKey][0], self, "",
143            QColorDialog.ColorDialogOption.ShowAlphaChannel)
144        if colour.isValid():
145            self.__coloursDict[colorKey][0] = colour
146            self.__updateSampleBackgroundColour(colorKey)
147
148    @pyqtSlot()
149    def __updateSampleTextColour(self, colourKey):
150        """
151        Private slot to update the text colour of all samples.
152
153        @param colourKey key of the diff colour
154        @type str
155        """
156        colour = self.__coloursDict[colourKey][0]
157        for sample in self.__allSamples:
158            pl = sample.palette()
159            pl.setColor(QPalette.ColorRole.Text, colour)
160            sample.setPalette(pl)
161            sample.repaint()
162
163    def __updateSampleBackgroundColour(self, colourKey):
164        """
165        Private slot to update the background colour of a sample.
166
167        @param colourKey key of the diff colour
168        @type str
169        """
170        sample = self.__coloursDict[colourKey][1]
171        if sample:
172            colour = self.__coloursDict[colourKey][0]
173            pl = sample.palette()
174            pl.setColor(QPalette.ColorRole.Base, colour)
175            sample.setPalette(pl)
176            sample.repaint()
177
178
179def create(dlg):
180    """
181    Module function to create the configuration page.
182
183    @param dlg reference to the configuration dialog
184    @return reference to the instantiated page (ConfigurationPageBase)
185    """
186    page = DiffColoursPage()
187    return page
188