148 lines
4.4 KiB
Python
148 lines
4.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
AZA Controller / Launcher — zentraler Einstieg.
|
|
|
|
Startet AZA Office, Praxis Chat, prueft Updates, zeigt Info.
|
|
Fuer Entwicklung: ``python aza_controller.py``
|
|
Produktion: spaeter ``aza_controller.exe`` im Installer.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import tkinter as tk
|
|
from tkinter import messagebox, ttk
|
|
|
|
from aza_start_panel import start_office, start_praxischat
|
|
from aza_update_core import format_version_label, load_local_version
|
|
from aza_updater import check_updates_interactive, show_app_info
|
|
|
|
_WIN_APP_ID = "ch.aza-medwork.controller.v1"
|
|
_ACCENT = "#1a5f8a"
|
|
_ACCENT_HOVER = "#164f73"
|
|
|
|
|
|
def _ensure_win32_app_user_model_id() -> None:
|
|
if sys.platform != "win32":
|
|
return
|
|
try:
|
|
import ctypes
|
|
|
|
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(_WIN_APP_ID)
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def _center_window(win: tk.Tk, width: int, height: int) -> None:
|
|
win.update_idletasks()
|
|
sw = win.winfo_screenwidth()
|
|
sh = win.winfo_screenheight()
|
|
x = max(0, (sw - width) // 2)
|
|
y = max(0, (sh - height) // 2)
|
|
win.geometry(f"{width}x{height}+{x}+{y}")
|
|
|
|
|
|
class AzAController:
|
|
def __init__(self) -> None:
|
|
self.root = tk.Tk()
|
|
self.root.title("AzA — Controller")
|
|
self.root.resizable(False, False)
|
|
self.root.configure(bg="#eef3f8")
|
|
_center_window(self.root, 420, 430)
|
|
|
|
ver = format_version_label(load_local_version())
|
|
header = ttk.Frame(self.root, padding=(20, 18, 20, 8))
|
|
header.pack(fill="x")
|
|
ttk.Label(header, text="AzA", font=("Segoe UI", 20, "bold")).pack(anchor="w")
|
|
ttk.Label(
|
|
header,
|
|
text="Controller / Launcher",
|
|
font=("Segoe UI", 10),
|
|
).pack(anchor="w", pady=(2, 0))
|
|
ttk.Label(header, text=ver, font=("Segoe UI", 9)).pack(anchor="w", pady=(6, 0))
|
|
|
|
body = ttk.Frame(self.root, padding=(20, 8, 20, 16))
|
|
body.pack(fill="both", expand=True)
|
|
|
|
self._mk_btn(body, "AZA Office starten", self._on_office).pack(fill="x", pady=(0, 8))
|
|
self._mk_btn(body, "Praxis Chat starten", self._on_chat).pack(fill="x", pady=(0, 8))
|
|
self._mk_btn(body, "Updates prüfen", self._on_updates).pack(fill="x", pady=(0, 8))
|
|
self._mk_btn(body, "Einstellungen / Info", self._on_info).pack(fill="x", pady=(0, 8))
|
|
self._mk_btn(body, "Beenden", self.root.destroy, secondary=True).pack(fill="x")
|
|
|
|
ttk.Label(
|
|
self.root,
|
|
text="AzA Medwork",
|
|
font=("Segoe UI", 8),
|
|
).pack(pady=(0, 12))
|
|
|
|
ico = None
|
|
try:
|
|
from pathlib import Path
|
|
|
|
p = Path(__file__).resolve().parent / "logo.ico"
|
|
if p.is_file():
|
|
ico = str(p)
|
|
except Exception:
|
|
pass
|
|
if ico and sys.platform == "win32":
|
|
try:
|
|
self.root.iconbitmap(ico)
|
|
except Exception:
|
|
pass
|
|
|
|
def _mk_btn(self, parent, text: str, cmd, *, secondary: bool = False) -> tk.Button:
|
|
bg = "#5a6d7d" if secondary else _ACCENT
|
|
hover = "#4a5d6d" if secondary else _ACCENT_HOVER
|
|
btn = tk.Button(
|
|
parent,
|
|
text=text,
|
|
font=("Segoe UI", 10, "bold"),
|
|
fg="#ffffff",
|
|
bg=bg,
|
|
activebackground=hover,
|
|
activeforeground="#ffffff",
|
|
relief="flat",
|
|
bd=0,
|
|
padx=14,
|
|
pady=10,
|
|
cursor="hand2",
|
|
command=cmd,
|
|
)
|
|
btn.bind("<Enter>", lambda _e: btn.configure(bg=hover))
|
|
btn.bind("<Leave>", lambda _e: btn.configure(bg=bg))
|
|
return btn
|
|
|
|
def _on_office(self) -> None:
|
|
ok, msg = start_office()
|
|
if not ok:
|
|
messagebox.showerror("AZA Office", msg, parent=self.root)
|
|
else:
|
|
self.root.destroy()
|
|
|
|
def _on_chat(self) -> None:
|
|
ok, msg = start_praxischat()
|
|
if not ok:
|
|
messagebox.showerror("Praxis Chat", msg, parent=self.root)
|
|
else:
|
|
self.root.destroy()
|
|
|
|
def _on_updates(self) -> None:
|
|
check_updates_interactive(parent=self.root)
|
|
|
|
def _on_info(self) -> None:
|
|
show_app_info(parent=self.root)
|
|
|
|
def run(self) -> None:
|
|
self.root.mainloop()
|
|
|
|
|
|
def main() -> int:
|
|
_ensure_win32_app_user_model_id()
|
|
AzAController().run()
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|