108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
# Copyright 2022 (c) Anna Schumaker.
|
|
"""Easy access to the settings table in our database."""
|
|
import sqlite3
|
|
from gi.repository import GObject
|
|
from . import table
|
|
|
|
|
|
class Setting(table.Row):
|
|
"""Base class for settings."""
|
|
|
|
key = GObject.Property(type=str)
|
|
|
|
@property
|
|
def primary_key(self) -> str:
|
|
"""Get the primary key for this setting."""
|
|
return self.key
|
|
|
|
|
|
class IntSetting(Setting):
|
|
"""An integer setting."""
|
|
|
|
value = GObject.Property(type=int)
|
|
|
|
|
|
class FloatSetting(Setting):
|
|
"""A float setting."""
|
|
|
|
value = GObject.Property(type=float)
|
|
|
|
|
|
class BoolSetting(Setting):
|
|
"""A boolean setting."""
|
|
|
|
value = GObject.Property(type=bool, default=False)
|
|
|
|
|
|
class StringSetting(Setting):
|
|
"""A string setting."""
|
|
|
|
value = GObject.Property(type=str)
|
|
|
|
|
|
class Table(table.Table):
|
|
"""Creates and manages our settings properties."""
|
|
|
|
def __getitem__(self, key: str) -> int | float | str | bool | None:
|
|
"""Get the value for a specific settings key."""
|
|
if (setting := self.lookup(key)) is not None:
|
|
return setting.value
|
|
|
|
def do_construct(self, type: str, value: any, **kwargs) -> table.Row:
|
|
"""Construct a new settings row."""
|
|
match type:
|
|
case "gint":
|
|
return IntSetting(value=int(value), **kwargs)
|
|
case "gdouble":
|
|
return FloatSetting(value=float(value), **kwargs)
|
|
case "gboolean":
|
|
value = str(value) == "True"
|
|
return BoolSetting(value=value, **kwargs)
|
|
case "gchararray":
|
|
return StringSetting(value=value, **kwargs)
|
|
|
|
def do_get_sort_key(self, setting: table.Row) -> list[str]:
|
|
"""Get the sort key for a specific setting."""
|
|
return setting.key.casefold().split(".")
|
|
|
|
def do_sql_delete(self, setting: table.Row) -> sqlite3.Cursor:
|
|
"""Delete a setting."""
|
|
return self.sql("DELETE FROM settings WHERE key=?", setting.key)
|
|
|
|
def do_sql_glob(self, glob: str) -> sqlite3.Cursor:
|
|
"""Filter the settings table."""
|
|
return self.sql("""SELECT key FROM settings
|
|
WHERE CASEFOLD(key) GLOB ?""", glob)
|
|
|
|
def do_sql_insert(self, key: str, type: str, value) -> sqlite3.Cursor:
|
|
"""Create a new settings row."""
|
|
return self.sql("""INSERT INTO settings (key, type, value)
|
|
VALUES (?, ?, ?) RETURNING *""",
|
|
key, type, str(value))
|
|
|
|
def do_sql_select_all(self) -> sqlite3.Cursor:
|
|
"""Load settings from the database."""
|
|
return self.sql("SELECT * FROM settings ORDER BY CASEFOLD(key)")
|
|
|
|
def do_sql_select_one(self, key: str) -> int | None:
|
|
"""Look up a setting by key."""
|
|
return self.sql("SELECT key FROM settings WHERE key=?", key)
|
|
|
|
def do_sql_update(self, setting: table.Row, column: str,
|
|
newval: any) -> sqlite3.Cursor:
|
|
"""Update a Setting."""
|
|
return self.sql(f"UPDATE settings SET {column}=? WHERE key=?",
|
|
str(newval), setting.key)
|
|
|
|
def bind_setting(self, key: str, target: GObject.GObject,
|
|
property: str) -> None:
|
|
"""Bind a setting to a target property."""
|
|
if (setting := self.lookup(key=key)) is None:
|
|
param = target.find_property(property)
|
|
setting = self.create(key=key, type=param.value_type.name,
|
|
value=target.get_property(property))
|
|
else:
|
|
target.set_property(property, setting.value)
|
|
setting.bind_property("value", target, property,
|
|
GObject.BindingFlags.BIDIRECTIONAL)
|