Edit on GitHub

sysmon_pytk.settings

Application settings.

  1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com>
  2# SPDX-License-Identifier: MIT
  3
  4"""
  5Application settings.
  6"""
  7
  8from __future__ import annotations
  9
 10from configparser import ConfigParser
 11from pathlib import Path
 12from typing import TYPE_CHECKING
 13
 14from .font_utils import MAIN_FONT_FAMILY, FontDescription, FontSlant, FontWeight
 15
 16if TYPE_CHECKING:
 17    from tkinter.font import Font
 18
 19
 20class FontSettings:  # pylint: disable=too-many-instance-attributes
 21    """
 22    Manage the fonts used in the application.
 23
 24    Attributes
 25    ----------
 26    config : ConfigParser
 27        A configuration file parser.
 28    section : str
 29        Which section of the configuration file to use.
 30    """
 31
 32    def __init__(self, config: ConfigParser, section: str) -> None:
 33        """
 34        Construct a Font Settings manager.
 35
 36        Parameters
 37        ----------
 38        config : ConfigParser
 39            A configuration file parser.
 40        section : str
 41            Which section of the configuration file to use.
 42        """
 43        self.config = config
 44        self.section = section
 45
 46    @property
 47    def name(self) -> str:
 48        """
 49        The font name to use in the application.
 50        """
 51        return self.config[self.section].get("name", fallback=MAIN_FONT_FAMILY)
 52
 53    @name.setter
 54    def name(self, fontname: str) -> None:
 55        self.config[self.section]["name"] = fontname
 56
 57    @property
 58    def size(self) -> int:
 59        """
 60        The font size to use in the application.
 61        """
 62        return self.config[self.section].getint("size", fallback=12)
 63
 64    @size.setter
 65    def size(self, fontsize: int) -> None:
 66        self.config[self.section]["size"] = f"{fontsize}"
 67
 68    @property
 69    def weight(self) -> FontWeight:
 70        """
 71        The font weight to use in the application.
 72        """
 73        weight = self.config[self.section].get("weight", fallback="normal")
 74        if weight == "bold":
 75            return "bold"
 76        return "normal"
 77
 78    @weight.setter
 79    def weight(self, weight: str) -> None:
 80        self.config[self.section]["weight"] = weight
 81
 82    @property
 83    def slant(self) -> FontSlant:
 84        """
 85        The font slant to use in the application.
 86        """
 87        slant = self.config[self.section].get("slant", fallback="roman")
 88        if slant == "italic":
 89            return "italic"
 90        return "roman"
 91
 92    @slant.setter
 93    def slant(self, slant: str) -> None:
 94        self.config[self.section]["slant"] = slant
 95
 96    @property
 97    def underline(self) -> bool:
 98        """
 99        The font underline flag to use in the application.
100        """
101        return self.config[self.section].getboolean("underline", fallback=False)
102
103    @underline.setter
104    def underline(self, underline: bool) -> None:
105        self.config[self.section]["underline"] = f"{underline}"
106
107    @property
108    def overstrike(self) -> bool:
109        """
110        The font overstrike flag to use in the application.
111        """
112        return self.config[self.section].getboolean("overstrike", fallback=False)
113
114    @overstrike.setter
115    def overstrike(self, overstrike: bool) -> None:
116        self.config[self.section]["overstrike"] = f"{overstrike}"
117
118    def get_full_font(self) -> FontDescription:
119        """
120        Get the full font specification to use in the application.
121        """
122        return FontDescription(
123            family=self.name,
124            size=self.size,
125            weight=self.weight,
126            slant=self.slant,
127            underline=self.underline,
128            overstrike=self.overstrike
129        )
130
131    def set_full_font(self, font: FontDescription) -> None:
132        """
133        Set the full font specification to use in the application.
134        """
135        self.name = font.family
136        self.size = font.size
137        self.weight = font.weight
138        self.slant = font.slant
139        self.underline = font.underline
140        self.overstrike = font.overstrike
141
142    def configure_font(self, font: Font) -> None:
143        """
144        Configure an existing Font to use the current settings.
145        """
146        font.configure(
147            family=self.name,
148            size=self.size,
149            weight=self.weight,
150            slant=self.slant,
151            underline=self.underline,
152            overstrike=self.overstrike
153        )
154
155
156class Settings:
157    """
158    Manage the application settings.
159
160    Attributes
161    ----------
162    filename : str
163        The full path to the configuration file.
164    config : ConfigParser
165        A configuration file parser.
166    regular_font : FontSettings
167        Font settings for the regular font.
168    fixed_font : FontSettings
169        Font settings for the monospace font.
170    """
171
172    def __init__(self, filename: str) -> None:
173        """
174        Construct a Settings manager.
175
176        Parameters
177        ----------
178        filename : str
179            The full path to the configuration file.
180        """
181        self.filename = filename
182        self.config = ConfigParser()
183        self.read_settings()
184        self.regular_font = FontSettings(self.config, "font")
185        self.fixed_font = FontSettings(self.config, "fixedfont")
186
187    def read_settings(self) -> None:
188        """
189        Read the settings from the configuration file.
190        """
191        self.config.read(self.filename)
192        if not self.config.has_section("general"):
193            self.config.add_section("general")
194        if not self.config.has_section("font"):
195            self.config.add_section("font")
196        if not self.config.has_section("fixedfont"):
197            self.config.add_section("fixedfont")
198
199    def write_settings(self) -> None:
200        """
201        Write the settings to the configuration file.
202        """
203        with Path(self.filename).open(mode="w", encoding="utf-8") as file:
204            self.config.write(file)
205
206    @property
207    def theme(self) -> str:
208        """
209        The application theme.
210        """
211        return self.config["general"].get("theme", fallback="Light")
212
213    @theme.setter
214    def theme(self, theme: str) -> None:
215        self.config["general"]["theme"] = theme
216
217    @property
218    def always_on_top(self) -> int:
219        """
220        The flag indicating whether the application should always be on top.
221        """
222        return self.config["general"].getint("always_on_top", fallback=0)
223
224    @always_on_top.setter
225    def always_on_top(self, always_on_top: int) -> None:
226        self.config["general"]["always_on_top"] = f"{always_on_top}"
227
228    @property
229    def add_menu_icon(self) -> int:
230        """
231        The flag indicating whether the application should add a menu icon.
232        """
233        return self.config["general"].getint("add_menu_icon", fallback=0)
234
235    @add_menu_icon.setter
236    def add_menu_icon(self, add_menu_icon: int) -> None:
237        self.config["general"]["add_menu_icon"] = f"{add_menu_icon}"
238
239    @property
240    def language(self) -> str:
241        """
242        The language to use.
243        """
244        return self.config["general"].get("language", fallback="en")
245
246    @language.setter
247    def language(self, language: str) -> None:
248        self.config["general"]["language"] = language
class FontSettings:
 21class FontSettings:  # pylint: disable=too-many-instance-attributes
 22    """
 23    Manage the fonts used in the application.
 24
 25    Attributes
 26    ----------
 27    config : ConfigParser
 28        A configuration file parser.
 29    section : str
 30        Which section of the configuration file to use.
 31    """
 32
 33    def __init__(self, config: ConfigParser, section: str) -> None:
 34        """
 35        Construct a Font Settings manager.
 36
 37        Parameters
 38        ----------
 39        config : ConfigParser
 40            A configuration file parser.
 41        section : str
 42            Which section of the configuration file to use.
 43        """
 44        self.config = config
 45        self.section = section
 46
 47    @property
 48    def name(self) -> str:
 49        """
 50        The font name to use in the application.
 51        """
 52        return self.config[self.section].get("name", fallback=MAIN_FONT_FAMILY)
 53
 54    @name.setter
 55    def name(self, fontname: str) -> None:
 56        self.config[self.section]["name"] = fontname
 57
 58    @property
 59    def size(self) -> int:
 60        """
 61        The font size to use in the application.
 62        """
 63        return self.config[self.section].getint("size", fallback=12)
 64
 65    @size.setter
 66    def size(self, fontsize: int) -> None:
 67        self.config[self.section]["size"] = f"{fontsize}"
 68
 69    @property
 70    def weight(self) -> FontWeight:
 71        """
 72        The font weight to use in the application.
 73        """
 74        weight = self.config[self.section].get("weight", fallback="normal")
 75        if weight == "bold":
 76            return "bold"
 77        return "normal"
 78
 79    @weight.setter
 80    def weight(self, weight: str) -> None:
 81        self.config[self.section]["weight"] = weight
 82
 83    @property
 84    def slant(self) -> FontSlant:
 85        """
 86        The font slant to use in the application.
 87        """
 88        slant = self.config[self.section].get("slant", fallback="roman")
 89        if slant == "italic":
 90            return "italic"
 91        return "roman"
 92
 93    @slant.setter
 94    def slant(self, slant: str) -> None:
 95        self.config[self.section]["slant"] = slant
 96
 97    @property
 98    def underline(self) -> bool:
 99        """
100        The font underline flag to use in the application.
101        """
102        return self.config[self.section].getboolean("underline", fallback=False)
103
104    @underline.setter
105    def underline(self, underline: bool) -> None:
106        self.config[self.section]["underline"] = f"{underline}"
107
108    @property
109    def overstrike(self) -> bool:
110        """
111        The font overstrike flag to use in the application.
112        """
113        return self.config[self.section].getboolean("overstrike", fallback=False)
114
115    @overstrike.setter
116    def overstrike(self, overstrike: bool) -> None:
117        self.config[self.section]["overstrike"] = f"{overstrike}"
118
119    def get_full_font(self) -> FontDescription:
120        """
121        Get the full font specification to use in the application.
122        """
123        return FontDescription(
124            family=self.name,
125            size=self.size,
126            weight=self.weight,
127            slant=self.slant,
128            underline=self.underline,
129            overstrike=self.overstrike
130        )
131
132    def set_full_font(self, font: FontDescription) -> None:
133        """
134        Set the full font specification to use in the application.
135        """
136        self.name = font.family
137        self.size = font.size
138        self.weight = font.weight
139        self.slant = font.slant
140        self.underline = font.underline
141        self.overstrike = font.overstrike
142
143    def configure_font(self, font: Font) -> None:
144        """
145        Configure an existing Font to use the current settings.
146        """
147        font.configure(
148            family=self.name,
149            size=self.size,
150            weight=self.weight,
151            slant=self.slant,
152            underline=self.underline,
153            overstrike=self.overstrike
154        )

Manage the fonts used in the application.

Attributes
  • config (ConfigParser): A configuration file parser.
  • section (str): Which section of the configuration file to use.
FontSettings(config: configparser.ConfigParser, section: str)
33    def __init__(self, config: ConfigParser, section: str) -> None:
34        """
35        Construct a Font Settings manager.
36
37        Parameters
38        ----------
39        config : ConfigParser
40            A configuration file parser.
41        section : str
42            Which section of the configuration file to use.
43        """
44        self.config = config
45        self.section = section

Construct a Font Settings manager.

Parameters
  • config (ConfigParser): A configuration file parser.
  • section (str): Which section of the configuration file to use.
name: str
47    @property
48    def name(self) -> str:
49        """
50        The font name to use in the application.
51        """
52        return self.config[self.section].get("name", fallback=MAIN_FONT_FAMILY)

The font name to use in the application.

size: int
58    @property
59    def size(self) -> int:
60        """
61        The font size to use in the application.
62        """
63        return self.config[self.section].getint("size", fallback=12)

The font size to use in the application.

weight: sysmon_pytk.font_utils.FontWeight
69    @property
70    def weight(self) -> FontWeight:
71        """
72        The font weight to use in the application.
73        """
74        weight = self.config[self.section].get("weight", fallback="normal")
75        if weight == "bold":
76            return "bold"
77        return "normal"

The font weight to use in the application.

83    @property
84    def slant(self) -> FontSlant:
85        """
86        The font slant to use in the application.
87        """
88        slant = self.config[self.section].get("slant", fallback="roman")
89        if slant == "italic":
90            return "italic"
91        return "roman"

The font slant to use in the application.

underline: bool
 97    @property
 98    def underline(self) -> bool:
 99        """
100        The font underline flag to use in the application.
101        """
102        return self.config[self.section].getboolean("underline", fallback=False)

The font underline flag to use in the application.

overstrike: bool
108    @property
109    def overstrike(self) -> bool:
110        """
111        The font overstrike flag to use in the application.
112        """
113        return self.config[self.section].getboolean("overstrike", fallback=False)

The font overstrike flag to use in the application.

def get_full_font(self) -> sysmon_pytk.font_utils.FontDescription:
119    def get_full_font(self) -> FontDescription:
120        """
121        Get the full font specification to use in the application.
122        """
123        return FontDescription(
124            family=self.name,
125            size=self.size,
126            weight=self.weight,
127            slant=self.slant,
128            underline=self.underline,
129            overstrike=self.overstrike
130        )

Get the full font specification to use in the application.

def set_full_font(self, font: sysmon_pytk.font_utils.FontDescription) -> None:
132    def set_full_font(self, font: FontDescription) -> None:
133        """
134        Set the full font specification to use in the application.
135        """
136        self.name = font.family
137        self.size = font.size
138        self.weight = font.weight
139        self.slant = font.slant
140        self.underline = font.underline
141        self.overstrike = font.overstrike

Set the full font specification to use in the application.

def configure_font(self, font: tkinter.font.Font) -> None:
143    def configure_font(self, font: Font) -> None:
144        """
145        Configure an existing Font to use the current settings.
146        """
147        font.configure(
148            family=self.name,
149            size=self.size,
150            weight=self.weight,
151            slant=self.slant,
152            underline=self.underline,
153            overstrike=self.overstrike
154        )

Configure an existing Font to use the current settings.

class Settings:
157class Settings:
158    """
159    Manage the application settings.
160
161    Attributes
162    ----------
163    filename : str
164        The full path to the configuration file.
165    config : ConfigParser
166        A configuration file parser.
167    regular_font : FontSettings
168        Font settings for the regular font.
169    fixed_font : FontSettings
170        Font settings for the monospace font.
171    """
172
173    def __init__(self, filename: str) -> None:
174        """
175        Construct a Settings manager.
176
177        Parameters
178        ----------
179        filename : str
180            The full path to the configuration file.
181        """
182        self.filename = filename
183        self.config = ConfigParser()
184        self.read_settings()
185        self.regular_font = FontSettings(self.config, "font")
186        self.fixed_font = FontSettings(self.config, "fixedfont")
187
188    def read_settings(self) -> None:
189        """
190        Read the settings from the configuration file.
191        """
192        self.config.read(self.filename)
193        if not self.config.has_section("general"):
194            self.config.add_section("general")
195        if not self.config.has_section("font"):
196            self.config.add_section("font")
197        if not self.config.has_section("fixedfont"):
198            self.config.add_section("fixedfont")
199
200    def write_settings(self) -> None:
201        """
202        Write the settings to the configuration file.
203        """
204        with Path(self.filename).open(mode="w", encoding="utf-8") as file:
205            self.config.write(file)
206
207    @property
208    def theme(self) -> str:
209        """
210        The application theme.
211        """
212        return self.config["general"].get("theme", fallback="Light")
213
214    @theme.setter
215    def theme(self, theme: str) -> None:
216        self.config["general"]["theme"] = theme
217
218    @property
219    def always_on_top(self) -> int:
220        """
221        The flag indicating whether the application should always be on top.
222        """
223        return self.config["general"].getint("always_on_top", fallback=0)
224
225    @always_on_top.setter
226    def always_on_top(self, always_on_top: int) -> None:
227        self.config["general"]["always_on_top"] = f"{always_on_top}"
228
229    @property
230    def add_menu_icon(self) -> int:
231        """
232        The flag indicating whether the application should add a menu icon.
233        """
234        return self.config["general"].getint("add_menu_icon", fallback=0)
235
236    @add_menu_icon.setter
237    def add_menu_icon(self, add_menu_icon: int) -> None:
238        self.config["general"]["add_menu_icon"] = f"{add_menu_icon}"
239
240    @property
241    def language(self) -> str:
242        """
243        The language to use.
244        """
245        return self.config["general"].get("language", fallback="en")
246
247    @language.setter
248    def language(self, language: str) -> None:
249        self.config["general"]["language"] = language

Manage the application settings.

Attributes
  • filename (str): The full path to the configuration file.
  • config (ConfigParser): A configuration file parser.
  • regular_font (FontSettings): Font settings for the regular font.
  • fixed_font (FontSettings): Font settings for the monospace font.
Settings(filename: str)
173    def __init__(self, filename: str) -> None:
174        """
175        Construct a Settings manager.
176
177        Parameters
178        ----------
179        filename : str
180            The full path to the configuration file.
181        """
182        self.filename = filename
183        self.config = ConfigParser()
184        self.read_settings()
185        self.regular_font = FontSettings(self.config, "font")
186        self.fixed_font = FontSettings(self.config, "fixedfont")

Construct a Settings manager.

Parameters
  • filename (str): The full path to the configuration file.
def read_settings(self) -> None:
188    def read_settings(self) -> None:
189        """
190        Read the settings from the configuration file.
191        """
192        self.config.read(self.filename)
193        if not self.config.has_section("general"):
194            self.config.add_section("general")
195        if not self.config.has_section("font"):
196            self.config.add_section("font")
197        if not self.config.has_section("fixedfont"):
198            self.config.add_section("fixedfont")

Read the settings from the configuration file.

def write_settings(self) -> None:
200    def write_settings(self) -> None:
201        """
202        Write the settings to the configuration file.
203        """
204        with Path(self.filename).open(mode="w", encoding="utf-8") as file:
205            self.config.write(file)

Write the settings to the configuration file.

theme: str
207    @property
208    def theme(self) -> str:
209        """
210        The application theme.
211        """
212        return self.config["general"].get("theme", fallback="Light")

The application theme.

always_on_top: int
218    @property
219    def always_on_top(self) -> int:
220        """
221        The flag indicating whether the application should always be on top.
222        """
223        return self.config["general"].getint("always_on_top", fallback=0)

The flag indicating whether the application should always be on top.

add_menu_icon: int
229    @property
230    def add_menu_icon(self) -> int:
231        """
232        The flag indicating whether the application should add a menu icon.
233        """
234        return self.config["general"].getint("add_menu_icon", fallback=0)

The flag indicating whether the application should add a menu icon.

language: str
240    @property
241    def language(self) -> str:
242        """
243        The language to use.
244        """
245        return self.config["general"].get("language", fallback="en")

The language to use.