gui.main

 1# Copyright (C) 2026  David Vaquero <pepesan@gmail.com>
 2#
 3# This program is free software: you can redistribute it and/or modify
 4# it under the terms of the GNU General Public License as published by
 5# the Free Software Foundation, either version 3 of the License, or
 6# (at your option) any later version.
 7#
 8# This program is distributed in the hope that it will be useful,
 9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16import sys
17import traceback
18import os
19
20from gui.utils.path_setup import setup_path, get_courses_dir
21setup_path()
22
23# Aplicar ajustes de pantalla ANTES de crear QApplication
24from lib.slides_config import (
25    get_display_settings as _get_display,
26    get_theme as _get_theme,
27    get_theme_overrides as _get_overrides,
28)
29from gui import theme as _theme
30# Tema se resuelve en main() tras crear QApplication (para detectar sistema en modo 'auto')
31# Aquí solo pre-cargamos para que _theme.c() no falle si algo lo usa antes
32_theme.setup('dark')
33_ds = _get_display()
34os.environ["QT_ENABLE_HIGHDPI_SCALING"]       = _ds['highdpi_scaling']
35os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"]     = _ds['auto_screen_scale']
36os.environ["QT_SCALE_FACTOR_ROUNDING_POLICY"] = _ds['scale_rounding_policy']
37os.environ["QT_SCALE_FACTOR"]                 = _ds['scale_factor']
38import lib.i18n as _i18n
39_i18n.setup()
40
41from PySide6.QtWidgets import QApplication, QMessageBox
42from gui.main_window import MainWindow
43from gui.dialogs.onboarding_dialog import OnboardingDialog
44
45
46def _excepthook(exc_type, exc_value, exc_tb):
47    msg = ''.join(traceback.format_exception(exc_type, exc_value, exc_tb))
48    dlg = QMessageBox()
49    dlg.setWindowTitle(_('Error inesperado'))
50    dlg.setText(str(exc_value))
51    dlg.setDetailedText(msg)
52    dlg.setIcon(QMessageBox.Icon.Critical)
53    dlg.exec()
54
55
56def _run_onboarding() -> bool:
57    """Muestra el onboarding si no hay directorio configurado. Devuelve True para continuar."""
58    if get_courses_dir() is not None:
59        return True
60    dlg = OnboardingDialog()
61    dlg.exec()
62    return True   # se continúa siempre; si omitió usará el directorio por defecto
63
64
65def _resolve_theme(requested: str, app) -> str:
66    """Si 'auto', detecta el tema del sistema; si no, devuelve el valor tal cual."""
67    if requested != 'auto':
68        return requested
69    from PySide6.QtGui import QPalette
70    bg = app.palette().color(QPalette.ColorRole.Window)
71    return 'dark' if bg.lightness() < 128 else 'light'
72
73
74def main():
75    app = QApplication(sys.argv)
76    font = app.font()
77    font.setPointSize(11)
78    app.setFont(font)
79    app.setApplicationName('Temario')
80    app.setOrganizationName('temario')
81    sys.excepthook = _excepthook
82
83    resolved = _resolve_theme(_get_theme(), app)
84    _theme.setup(resolved)
85    _theme.set_overrides(_get_overrides())
86    _theme.apply_global(app)
87
88    _run_onboarding()
89
90    window = MainWindow()
91    window.show()
92    sys.exit(app.exec())
93
94
95if __name__ == '__main__':
96    main()
def main():
75def main():
76    app = QApplication(sys.argv)
77    font = app.font()
78    font.setPointSize(11)
79    app.setFont(font)
80    app.setApplicationName('Temario')
81    app.setOrganizationName('temario')
82    sys.excepthook = _excepthook
83
84    resolved = _resolve_theme(_get_theme(), app)
85    _theme.setup(resolved)
86    _theme.set_overrides(_get_overrides())
87    _theme.apply_global(app)
88
89    _run_onboarding()
90
91    window = MainWindow()
92    window.show()
93    sys.exit(app.exec())