update
This commit is contained in:
147
AzA march 2026/aza_controller.py
Normal file
147
AzA march 2026/aza_controller.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# -*- 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())
|
||||
Reference in New Issue
Block a user