Skip to content

Commit 6e028e0

Browse files
committed
feat(store): update store screenshots generator, icons, and test suite
1 parent 8f2e349 commit 6e028e0

21 files changed

Lines changed: 606 additions & 167 deletions

MethodenAnalyser.png

81.6 KB
Loading

MethodenAnalyser3.py

Lines changed: 134 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
from dataclasses import dataclass, field
2020
from functools import lru_cache
2121

22+
try:
23+
from translator import TranslationSystem
24+
except Exception: # pragma: no cover - Uebersetzung ist optional
25+
TranslationSystem = None
26+
2227
# ============================================================================
2328
# KONSTANTEN
2429
# ============================================================================
@@ -43,6 +48,88 @@
4348
EXIT_FINDINGS = 2
4449
EXIT_PARTIAL_ERROR = 3
4550

51+
# ============================================================================
52+
# SPRACHE / KONFIGURATION (Welle-1 U1: sichtbarer DE/EN-Sprachschalter)
53+
# ============================================================================
54+
55+
SUPPORTED_LANGUAGES = ("de", "en")
56+
DEFAULT_LANGUAGE = "de"
57+
58+
# Erste Zeile der Willkommensnachricht je Sprache (fuer Live-Neurendern beim Sprachwechsel)
59+
_WELCOME_HEADS = (
60+
"Willkommen beim Python Code Analyzer!",
61+
"Welcome to Python Code Analyzer!",
62+
)
63+
64+
65+
def _config_dir() -> pathlib.Path:
66+
"""Per-User-Konfigverzeichnis (auch bei read-only Store-Installation schreibbar)."""
67+
if sys.platform.startswith("win"):
68+
base = os.environ.get("APPDATA") or os.path.expanduser("~")
69+
else:
70+
base = os.environ.get("XDG_CONFIG_HOME") or os.path.join(
71+
os.path.expanduser("~"), ".config"
72+
)
73+
return pathlib.Path(base) / "MethodenAnalyser"
74+
75+
76+
def _config_path() -> pathlib.Path:
77+
return _config_dir() / "config.json"
78+
79+
80+
def load_app_config() -> Dict[str, Any]:
81+
"""Liest die persistente App-Konfiguration (leer bei Fehlen/Korruption)."""
82+
try:
83+
with open(_config_path(), "r", encoding="utf-8") as handle:
84+
data = json.load(handle)
85+
return data if isinstance(data, dict) else {}
86+
except (OSError, ValueError):
87+
return {}
88+
89+
90+
def save_app_config(config: Dict[str, Any]) -> bool:
91+
"""Speichert die App-Konfiguration; True bei Erfolg."""
92+
try:
93+
_config_dir().mkdir(parents=True, exist_ok=True)
94+
with open(_config_path(), "w", encoding="utf-8") as handle:
95+
json.dump(config, handle, indent=2, ensure_ascii=False)
96+
return True
97+
except OSError:
98+
return False
99+
100+
101+
def get_saved_language() -> str:
102+
"""Gespeicherte Sprache oder Default, validiert gegen SUPPORTED_LANGUAGES."""
103+
lang = load_app_config().get("language", DEFAULT_LANGUAGE)
104+
return lang if lang in SUPPORTED_LANGUAGES else DEFAULT_LANGUAGE
105+
106+
107+
def set_saved_language(lang: str) -> bool:
108+
"""Persistiert die gewaehlte Sprache in der App-Konfiguration."""
109+
if lang not in SUPPORTED_LANGUAGES:
110+
return False
111+
config = load_app_config()
112+
config["language"] = lang
113+
return save_app_config(config)
114+
115+
116+
_TRANSLATOR = None
117+
118+
119+
def get_translator():
120+
"""Lazy-Singleton des TranslationSystem, mit gespeicherter Sprache initialisiert."""
121+
global _TRANSLATOR
122+
if _TRANSLATOR is None and TranslationSystem is not None:
123+
_TRANSLATOR = TranslationSystem(get_saved_language())
124+
return _TRANSLATOR
125+
126+
127+
def _t(key: str) -> str:
128+
"""Uebersetzt key in die aktuelle Sprache (Fallback: key selbst)."""
129+
translator = get_translator()
130+
return translator.t(key) if translator is not None else key
131+
132+
46133
# Analyse Konfiguration
47134
SIMILARITY_THRESHOLD = 0.8
48135

@@ -1552,6 +1639,11 @@ def progress_cb(cur, tot, fp):
15521639
messagebox.showerror("Fehler", str(e))
15531640

15541641

1642+
def _build_welcome_text() -> str:
1643+
"""Baut die uebersetzte Willkommensnachricht inkl. eingesetztem Shortcut-Hinweis."""
1644+
return _t("welcome_body").replace("{shortcut}", _get_keyboard_shortcut_hint())
1645+
1646+
15551647
def create_gui() -> None:
15561648
"""Erstellt und startet die GUI-Anwendung."""
15571649
root = tk.Tk()
@@ -1570,20 +1662,13 @@ def create_gui() -> None:
15701662
def show_info_dialog() -> None:
15711663
messagebox.showinfo(
15721664
"Python Code Analyzer",
1573-
f"Python Code Analyzer v{TOOL_VERSION}\n\n"
1574-
"Analysiert Python-Dateien auf:\n"
1575-
"• Fehlende Definitionen\n"
1576-
"• Ungenutzte Definitionen\n"
1577-
"• Ungenutzte Imports\n"
1578-
"• Dynamische Aufrufe\n"
1579-
"• Import-Scope-Probleme\n\n"
1580-
"© 2026 - Optimierte Version"
1665+
_t("info_body").replace("{version}", TOOL_VERSION),
15811666
)
15821667

15831668
# Analyse-Button
15841669
btn = tk.Button(
15851670
button_frame,
1586-
text="📂 Datei analysieren",
1671+
text=_t("btn_analyze_file"),
15871672
command=lambda: run_analysis(output),
15881673
bg="#4CAF50",
15891674
fg="white",
@@ -1597,7 +1682,7 @@ def show_info_dialog() -> None:
15971682
# Info-Button
15981683
info_btn = tk.Button(
15991684
button_frame,
1600-
text="ℹ️ Info",
1685+
text=_t("btn_info"),
16011686
command=show_info_dialog,
16021687
bg="#2196F3",
16031688
fg="white",
@@ -1611,7 +1696,7 @@ def show_info_dialog() -> None:
16111696
# Auto-Fix Button
16121697
fix_btn = tk.Button(
16131698
button_frame,
1614-
text="🔧 Auto-Fix Imports",
1699+
text=_t("btn_autofix"),
16151700
command=lambda: auto_fix_unused_imports(output),
16161701
bg="#FF9800",
16171702
fg="white",
@@ -1625,7 +1710,7 @@ def show_info_dialog() -> None:
16251710
# NEU: Projekt-Analyse Button
16261711
project_btn = tk.Button(
16271712
button_frame,
1628-
text="Projekt analysieren",
1713+
text=_t("btn_analyze_project"),
16291714
command=lambda: run_project_analysis(output),
16301715
bg="#9C27B0",
16311716
fg="white",
@@ -1658,17 +1743,43 @@ def show_info_dialog() -> None:
16581743
output.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 10))
16591744

16601745
# Willkommensnachricht
1661-
welcome_text = (
1662-
"Willkommen beim Python Code Analyzer!\n\n"
1663-
f"{_get_keyboard_shortcut_hint()}\n\n"
1664-
"Klicken Sie auf 'Datei analysieren', um eine Python-Datei zu untersuchen.\n\n"
1665-
"Die Analyse umfasst:\n"
1666-
"• Fehlende und ungenutzte Definitionen\n"
1667-
"• Import-Analyse und -Optimierung\n"
1668-
"• Dynamische Methodenaufrufe\n"
1669-
"• Mögliche Tippfehler\n"
1746+
output.insert(tk.END, _build_welcome_text())
1747+
1748+
# --- Menue "Sprache / Language" (Welle-1 U1: sichtbarer DE/EN-Schalter) ---
1749+
translator = get_translator()
1750+
current_lang = translator.get_language() if translator is not None else get_saved_language()
1751+
lang_var = tk.StringVar(value=current_lang)
1752+
1753+
def apply_language(lang: str) -> None:
1754+
"""Wechselt Sprache, persistiert sie und stellt die Oberflaeche live um."""
1755+
if translator is not None:
1756+
translator.set_language(lang)
1757+
set_saved_language(lang)
1758+
lang_var.set(lang)
1759+
btn.config(text=_t("btn_analyze_file"))
1760+
info_btn.config(text=_t("btn_info"))
1761+
fix_btn.config(text=_t("btn_autofix"))
1762+
project_btn.config(text=_t("btn_analyze_project"))
1763+
shortcut_hint.config(text=_get_keyboard_shortcut_hint())
1764+
# Willkommenstext nur neu rendern, solange keine Analyse-Ausgabe angezeigt wird.
1765+
if output.get("1.0", "1.end").strip() in _WELCOME_HEADS:
1766+
output.delete("1.0", tk.END)
1767+
output.insert(tk.END, _build_welcome_text())
1768+
messagebox.showinfo("Sprache / Language", _t("lang_switched_msg"))
1769+
1770+
menubar = tk.Menu(root)
1771+
lang_menu = tk.Menu(menubar, tearoff=0)
1772+
lang_menu.add_radiobutton(
1773+
label="Deutsch", value="de", variable=lang_var,
1774+
command=lambda: apply_language("de"),
16701775
)
1671-
output.insert(tk.END, welcome_text)
1776+
lang_menu.add_radiobutton(
1777+
label="English", value="en", variable=lang_var,
1778+
command=lambda: apply_language("en"),
1779+
)
1780+
menubar.add_cascade(label=_t("menu_language"), menu=lang_menu)
1781+
root.config(menu=menubar)
1782+
16721783
_register_gui_shortcuts(
16731784
root,
16741785
analyze_file_cb=lambda: run_analysis(output),
@@ -1683,7 +1794,7 @@ def show_info_dialog() -> None:
16831794

16841795
def _get_keyboard_shortcut_hint() -> str:
16851796
"""Liefert den sichtbaren Kurzhinweis für die Hauptaktionen der GUI."""
1686-
return "Tastatur: Alt+D Datei | Alt+P Projekt | Alt+F Auto-Fix | F1 Info"
1797+
return _t("shortcut_hint")
16871798

16881799

16891800
def _register_gui_shortcuts(

0 commit comments

Comments
 (0)