{"id":130,"date":"2026-03-16T18:39:43","date_gmt":"2026-03-16T17:39:43","guid":{"rendered":"https:\/\/callerscaddy.de\/?page_id=130"},"modified":"2026-06-19T09:24:44","modified_gmt":"2026-06-19T07:24:44","slug":"release-notes","status":"publish","type":"page","link":"https:\/\/callerscaddy.de\/en\/release-notes\/","title":{"rendered":"Release Notes \u2013 Callers Caddy"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Versionierung: <code>0.XX<\/code> = Prototyp-Phase (XX = Prototyp-Nummer).<br>Ab offiziellem Launch wird auf <code>2.0<\/code> umgestellt.<br>Die Versionen 1.xx bleiben f\u00fcr die alte Version offen<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"667\" src=\"https:\/\/callerscaddy.de\/wp-content\/uploads\/2026\/03\/callers-caddy-release-notes.jpg\" alt=\"\" class=\"wp-image-235\" srcset=\"https:\/\/callerscaddy.de\/wp-content\/uploads\/2026\/03\/callers-caddy-release-notes.jpg 1000w, https:\/\/callerscaddy.de\/wp-content\/uploads\/2026\/03\/callers-caddy-release-notes-300x200.jpg 300w, https:\/\/callerscaddy.de\/wp-content\/uploads\/2026\/03\/callers-caddy-release-notes-768x512.jpg 768w, https:\/\/callerscaddy.de\/wp-content\/uploads\/2026\/03\/callers-caddy-release-notes-18x12.jpg 18w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.106 \u2014 Zentrale Icons, Farben aus dem Theme (2026-06-18)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features \/ Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Einheitliches Icon-Konzept f\u00fcr alle Themes:<\/strong> Alle Icons liegen jetzt zentral in einem gemeinsamen <code>images\/<\/code>-Ordner statt in jedem Theme dupliziert. Geometrie und Design werden einmal zentral gepflegt; die <strong>Farbe kommt ausschlie\u00dflich aus den Theme-Werten<\/strong>.<\/li>\n\n\n\n<li>Neuer Theme-Farb-Key <strong><code>icon_color<\/code><\/strong> (zus\u00e4tzlich zum bestehenden <code>title_icon<\/code>). Iconfarben lassen sich damit pro Theme rein \u00fcber <code>skin.json<\/code> steuern \u2014 ganz ohne eigene Bilddateien. Eigene Themes zu gestalten wird dadurch deutlich einfacher.<\/li>\n\n\n\n<li>Alle Themes nutzen dasselbe Icon-Set (modern, Outline-Stil); bisher abweichende Designs (win11, elegant) wurden angeglichen.<\/li>\n\n\n\n<li>Semantische Akzentfarben bleiben fest (Highlight-Gelb, Text-Color-Rot).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes (Theme-Feinschliff)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Spinbox-\/Combobox-Pfeile<\/strong> waren in hellen Themes (light\/win11) dunkel auf blauem Button-Grund (schlecht lesbar) \u2014 sie folgen jetzt <code>icon_color<\/code> und sind dort wei\u00df.<\/li>\n\n\n\n<li><strong>Splitter-Trennlinie<\/strong> (z.B. Planner zwischen Pool und Playlist) war ungestylt und erschien fast wei\u00df \u2014 sie nutzt jetzt die Theme-Trennfarbe wie die Dock-Trenner.<\/li>\n\n\n\n<li><strong>\u201e\u2026&#8220;-Buttons f\u00fcr Datei-Dialoge<\/strong> zeigten die drei Punkte nicht (Button-Padding schnitt den Text bei fester schmaler Breite ab) \u2014 eigene schmale Button-Variante, Punkte wieder sichtbar.<\/li>\n\n\n\n<li>Notes-Widget: Zoom-Icons werden wieder angezeigt (nutzen nun den zentralen Icon-Cache).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technik<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>SkinManager<\/code> f\u00e4rbt die zentralen Template-SVGs beim Theme-Laden mit den Theme-Farben ein (Temp-Cache); QSS referenziert Icons \u00fcber <code>{{icon_path}}<\/code>, Code \u00fcber <code>skin_mgr.icon_dir<\/code>. Dokumentation: <code>1_Source\/docs\/17_theming_icons.md<\/code> und `1_So<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.105 \u2014 Japanisch als dritte Sprache (2026-06-18)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Japanische Programmsprache (\u65e5\u672c\u8a9e):<\/strong> Callers Caddy l\u00e4sst sich jetzt auf Japanisch umstellen. Die gesamte Oberfl\u00e4che (Men\u00fcs, Dialoge, Tooltips, Meldungen, Tutorials, Migration und Class Designer \u2014 rund 1.460 Texte) wurde \u00fcbersetzt.<\/li>\n\n\n\n<li>Auswahl beim Erststart (dritter Button \u201e\u65e5\u672c\u8a9e\u3067\u958b\u59cb&#8220;) sowie jederzeit \u00fcber <strong>Einstellungen \u2192 Sprache<\/strong> bzw. das Sprach-Men\u00fc.<\/li>\n\n\n\n<li><strong>Square-Dance-Fachbegriffe bleiben bewusst englisch<\/strong> (z.B. Patter, Singing Call, Tip, Loop, BPM, Pitch, Beat Snap) \u2014 so wie international und auch von japanischen Callern \u00fcblich.<\/li>\n\n\n\n<li>Deutsch und Englisch sind unver\u00e4ndert: Die japanische \u00dcbersetzung wurde rein additiv erg\u00e4nzt, bestehende Sprachen wurden an keiner Stelle angetastet.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Lyrics-Toolbar bricht bei schmalem Dock um:<\/strong> Die Buttons oben im Lyrics-Fenster (Auto-Scroll, Auto-Size, Auto-Width, Zoom, Bearbeiten) leiten ihre Breite aus ihrem Inhalt ab und brechen in die n\u00e4chste Zeile um, wenn das Widget schmaler wird als die Buttonzeile vertr\u00e4gt \u2014 statt abgeschnitten zu werden oder eine Mindestbreite zu erzwingen. Gleiches Umbruch-Verhalten wie bereits bei Songliste und Playlist.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technik<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Logfiles bleiben sprachneutral lesbar:<\/strong> Diagnose-\/Support-Logs (Crash-Logs, rules.log, perf_log.txt, System-Report) waren und bleiben unabh\u00e4ngig von der UI-Sprache (technisch\/englisch). Das <strong>Migrations-Detaillog<\/strong> wird ab jetzt bewusst immer auf Englisch geschrieben (samt Live-Anzeige w\u00e4hrend der Migration), damit es f\u00fcr den Support unabh\u00e4ngig von der gew\u00e4hlten Sprache lesbar bleibt \u2014 die \u00fcbrige Oberfl\u00e4che des Migrationstools bleibt in der Nutzersprache.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.104 \u2014 Massen-L\u00f6schen gro\u00dfer Songmengen (2026-06-17)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer Reiter \u201eMassen-L\u00f6schen\u201c im Potential-Fenster (BL-148):<\/strong> Entfernt eine gro\u00dfe Menge Songs in einem Rutsch aus der Datenbank \u2014 gedacht f\u00fcr den Fall, dass versehentlich zu viele Songs geladen wurden (z.B. ein falscher Ordner beim Import).<\/li>\n\n\n\n<li><strong>Mehrfach sortierbare Liste<\/strong> mit den Spalten Typ (P\/S\/PS), Hinzugef\u00fcgt (Datum), Titel, Label, Genre, ERR und Qualit\u00e4t \u2014 jede Spalte per Klick auf den Kopf sortierbar, um den falschen Schwung schnell zu isolieren.<\/li>\n\n\n\n<li><strong>Komfortable Mehrfachauswahl:<\/strong> Shift+Klick markiert einen zusammenh\u00e4ngenden Bereich, Strg+Klick einzelne Zeilen, Strg+A alles in der Ansicht.<\/li>\n\n\n\n<li><strong>Eine einzige Sicherheitsabfrage<\/strong> f\u00fcr den ganzen Vorgang (keine R\u00fcckfrage pro Song), danach wird ohne weitere Unterbrechung gel\u00f6scht.<\/li>\n\n\n\n<li><strong>Historiendaten:<\/strong> Liegen zu den ausgew\u00e4hlten Songs Abspielverl\u00e4ufe vor, wird einmal gefragt, ob diese mitgel\u00f6scht werden sollen (Standard: Nein \u2014 die Historie kann sp\u00e4ter \u00fcber \u201eVerwaiste Historie\u201c bereinigt werden).<\/li>\n\n\n\n<li>Die Musikdateien auf der Festplatte werden dabei nicht angetastet.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technik \/ Performance<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die Songliste des Reiters wird <strong>erst beim \u00d6ffnen<\/strong> geladen (kein Start-Overhead) und das L\u00f6schen l\u00e4uft im Hintergrund-Thread, damit ein laufender Song nie unterbrochen wird. Bei aktivem Performance-Log werden Messpunkte (DB-Abfrage, Genre-Zuordnung, Tabellenaufbau, L\u00f6schvorgang) protokolliert.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.103 \u2014 Lyrics: Word- (DOCX) und PDF-Dateien anzeigen (2026-06-16)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Lyrics als Word-Dokument (.docx) anzeigen:<\/strong> Lyrics und Cuesheets, die als Word-Datei vorliegen, lassen sich jetzt direkt mit einem Song verkn\u00fcpfen und im Lyrics-Fenster anzeigen \u2013 inklusive Schriftgr\u00f6\u00dfen, gro\u00dfem zentriertem Titel, Einr\u00fcckungen, Fett\/Kursiv\/Unterstrichen sowie farbigen Text- und Hintergrund-Markierungen (z.B. die typischen gelben\/farbigen Tag-Markierungen). Es ist keine zus\u00e4tzliche Software (kein Word) n\u00f6tig.<\/li>\n\n\n\n<li><strong>Lyrics als PDF anzeigen:<\/strong> PDF-Dateien k\u00f6nnen ebenfalls als Lyrics verkn\u00fcpft und angezeigt werden \u2013 als schnelle Text-Leseansicht des Call-Texts. Hinweis: PDF wird bewusst nur als Text dargestellt; farbige Markierungen und das exakte Layout aus dem PDF werden dabei nicht \u00fcbernommen. Wer die volle Formatierung mit Markierungen braucht, verwendet daf\u00fcr Word, RTF oder HTML.<\/li>\n\n\n\n<li><strong>Bearbeiten von Word-\/PDF-Lyrics:<\/strong> Word und PDF sind reine Anzeigeformate. Wer ein solches Lyric bearbeiten m\u00f6chte, dem bietet Callers Caddy an, daraus eine bearbeitbare HTML-Kopie anzulegen (genau wie bisher bei RTF und Text). Die Originaldatei bleibt dabei unver\u00e4ndert.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Datei-Auswahl, automatischer Lyrics-Import beim Hinzuf\u00fcgen von Songs und die Migration aus der alten Version erkennen jetzt auch <code>.docx<\/code>&#8211; und <code>.pdf<\/code>-Dateien.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.102 \u2014 Startprobleme behoben: \u201el\u00e4uft bereits&#8220;, Audio auf ARM-Windows, Theme-Wechsel (2026-06-16)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u201eCallers Caddy l\u00e4uft bereits&#8220; trotz geschlossenem Programm \u2013 behoben:<\/strong> Bei einer Installation in gesch\u00fctzten Ordnern (z.B. <code>C:\\Programme\\\u2026<\/code>) lie\u00df sich Callers Caddy nicht starten \u2013 es kam die Meldung, das Programm laufe bereits, obwohl es geschlossen war. Behelfen konnte man sich nur mit \u201eAls Administrator ausf\u00fchren&#8220;. Ursache war die interne Sperrdatei, die im Programmordner abgelegt wurde, wo normale Benutzer nicht schreiben d\u00fcrfen. Sie liegt jetzt in einem immer beschreibbaren, benutzereigenen tempor\u00e4ren Ordner \u2013 der Admin-Trick ist nicht mehr n\u00f6tig. Mehrere getrennte Installationen blockieren sich dabei nicht gegenseitig.<\/li>\n\n\n\n<li><strong>Absturz beim Start auf Windows-on-ARM (z.B. Apple-Mac mit Parallels) \u2013 behoben:<\/strong> Lief Callers Caddy unter einem Windows auf ARM-Basis (etwa Windows 11 in Parallels auf einem MacBook), st\u00fcrzte es direkt beim Start mit <code>error 0x7e<\/code> ab, weil das Audio-System f\u00e4lschlich eine ARM-Variante der Audio-Bibliothek suchte, die nicht mitgeliefert wird. Callers Caddy nutzt jetzt korrekt die mitgelieferte 64-bit-Bibliothek (\u00fcber die Windows-Emulation) und startet auch in dieser Umgebung. Zus\u00e4tzlich rei\u00dft ein nicht ladbares Audio-System den Start an dieser Stelle nicht mehr roh ab, sondern wird sauber abgefangen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Theme\/Skin wechselt jetzt sofort:<\/strong> Eine \u00c4nderung von \u201eSkin \/ Theme&#8220; in den Einstellungen wird unmittelbar \u00fcbernommen \u2013 ein Neustart ist nicht mehr erforderlich.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.101 \u2014 Verst\u00e4ndliche Meldung statt Absturz, wenn das Audio-System blockiert ist (2026-06-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Kein roher Absturz mehr beim Start, wenn die Audio-Komponente nicht geladen werden kann:<\/strong> Auf manchen Rechnern brach Callers Caddy direkt beim Start mit einem unverst\u00e4ndlichen Python-Fehlerfenster ab (<code>PortAudio library not found<\/code>, <code>error 0x7e<\/code>). Ursache ist fast immer der Rechner, nicht das Programm \u2014 meist ein Virenscanner, der die Audio-Datei <code>libportaudio64bit.dll<\/code> blockiert oder in die Quarant\u00e4ne verschiebt, oder eine heruntergeladene ZIP-Datei, die vor dem Entpacken nicht \u201ezugelassen&#8220; wurde (Windows-Sperre). Bisher passierte dieser Fehler so fr\u00fch, dass kein Hinweisfenster m\u00f6glich war.<\/li>\n\n\n\n<li><strong>Klartext-Hinweis mit L\u00f6sungsweg:<\/strong> L\u00e4sst sich das Audio-System nicht laden, erscheint jetzt ein verst\u00e4ndliches Fenster, das die wahrscheinliche Ursache nennt und Schritt f\u00fcr Schritt erkl\u00e4rt, wie man sie behebt (Virenscanner-Ausnahme bzw. ZIP vor dem Entpacken freigeben).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen (Diagnose)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Crash-Protokollierung greift jetzt von der allerersten Sekunde an:<\/strong> Der Absturz-Logger wird nun ganz fr\u00fch aktiviert \u2014 noch bevor die Audio-Komponenten geladen werden. Dadurch werden ab sofort auch Abst\u00fcrze <em>beim Programmstart<\/em> in eine Logdatei geschrieben (<code>logs\\crashes<\/code>), die bisher spurlos blieben.<\/li>\n\n\n\n<li><strong>Gezielte Audio-Diagnose:<\/strong> Schl\u00e4gt das Laden des Audio-Systems fehl, schreibt Callers Caddy automatisch eine Diagnosedatei. Sie pr\u00fcft unter anderem, ob die Audio-Datei \u00fcberhaupt noch vorhanden ist und lesbar ist \u2014 so l\u00e4sst sich unterscheiden, ob der Virenscanner sie <em>gel\u00f6scht\/in Quarant\u00e4ne<\/em> verschoben hat oder ob sie <em>vorhanden, aber blockiert<\/em> ist (was der Windows-Fehlercode allein nicht verr\u00e4t). Der Hinweisdialog nennt den Speicherort der Datei f\u00fcr eine R\u00fcckfrage beim Support.<\/li>\n\n\n\n<li><strong>Erkennung von Sonderzeichen im Installationspfad:<\/strong> Die Diagnose pr\u00fcft jetzt auch, ob der Programmpfad Sonderzeichen enth\u00e4lt (z.B. Umlaute oder Diakritika im Benutzernamen wie <code>C:\\Users\\Tom\u00e1\u0161\\\u2026<\/code>). Solche Pfade sind eine bekannte, regionsabh\u00e4ngige Ursache daf\u00fcr, dass die Audio-Bibliothek unter Windows nicht geladen werden kann \u2014 die Diagnose weist dann direkt darauf hin (Abhilfe: in einen Pfad ohne Sonderzeichen installieren, z.B. <code>C:\\Callers_Caddy<\/code>).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.100 \u2014 Relative Musikpfade: verstreute Bibliotheken \u00fcber mehrere Ordner (2026-06-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Funktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Songs d\u00fcrfen jetzt in beliebig tiefen Unterordnern liegen:<\/strong> Bisher merkte sich Callers Caddy zu jedem Song nur den reinen Dateinamen und suchte ihn direkt in den (bis zu vier) Musikpfaden. Wer seine Musik in viele Unterordner sortiert hat, stie\u00df damit an Grenzen. Jetzt wird zu jedem Song der <strong>relative Pfad innerhalb seines Musikpfads<\/strong> gespeichert (z.B. <code>Singing Calls\/Country\/song.mp3<\/code>). So gen\u00fcgen weiterhin die vier Musikpfade als Wurzeln \u2014 die Unterordner-Struktur darunter kann beliebig gro\u00df sein.<\/li>\n\n\n\n<li><strong>Bis zu vier Wurzelpfade, auch auf verschiedenen Laufwerken:<\/strong> Die vier Musikpfade gelten als eigenst\u00e4ndige Wurzeln und d\u00fcrfen auf unterschiedlichen Laufwerken liegen (z.B. C:, D:, E:, F:). Ein Song wird relativ zu seinem Musikpfad gespeichert; beim Abspielen werden die Pfade der Reihe nach durchprobiert.<\/li>\n\n\n\n<li><strong>Neues Werkzeug \u201eMusikbibliothek re-indexieren&#8220; (Men\u00fc Pfade):<\/strong> Durchsucht alle konfigurierten Musikpfade rekursiv und hebt bestehende Songs, deren Datei in einem Unterordner liegt, automatisch auf den passenden relativen Pfad \u2014 so werden bisher nicht auffindbare Songs wieder abspielbar. L\u00e4uft im Hintergrund, ohne einen laufenden Song zu st\u00f6ren. Am Ende erscheint ein Bericht (aktualisiert \/ mehrdeutig \/ weiterhin fehlend). Dateien gleichen Namens in mehreren Ordnern werden bewusst nicht geraten, sondern zur manuellen Zuordnung gemeldet.<\/li>\n\n\n\n<li><strong>Import beh\u00e4lt die Ordnerstruktur:<\/strong> Beim Import \u201eam Ort belassen&#8220; wird der gew\u00e4hlte Wurzelordner als Musikpfad eingetragen und jeder Song relativ dazu gespeichert \u2014 inklusive Unterordner.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Einheitliche, portable Pfadspeicherung:<\/strong> Relative Pfade werden \u00fcberall einheitlich mit Schr\u00e4gstrich <code>\/<\/code> gespeichert (statt gemischter Schr\u00e4gstriche). Eine einmalige Datenbank-Migration r\u00e4umt \u00e4ltere Eintr\u00e4ge automatisch auf. Das macht die Datenbank robuster beim Verschieben auf andere Rechner oder USB-Sticks.<\/li>\n\n\n\n<li><strong>Datei-Auswahl an allen Stellen vereinheitlicht:<\/strong> Der Datei-Button im Song-Datensatz, die Varianten-Verwaltung und die Lyrics-Auswahl ermitteln den relativen Pfad jetzt gegen alle Musikpfade einheitlich.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Migrations-Tool<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Kopieren oder Verkn\u00fcpfen w\u00e4hlbar:<\/strong> Wie beim normalen Import fragt die Migration jetzt, ob die Musikdateien ins Ziel kopiert oder an ihrem Ort belassen und nur verkn\u00fcpft werden sollen. Verkn\u00fcpfen spart Speicherplatz und ist ideal f\u00fcr gro\u00dfe, verstreute Bibliotheken \u2014 die Quellordner werden dabei automatisch als Musikpfade in die Ziel-Konfiguration eingetragen.<\/li>\n\n\n\n<li><strong>Wurzelverzeichnis der Musikbibliothek:<\/strong> Die Migration fragt das Wurzelverzeichnis ab und speichert jeden Song relativ dazu \u2014 die Unterordner-Struktur bleibt erhalten.<\/li>\n\n\n\n<li><strong>Unterordner werden vollst\u00e4ndig durchsucht (CC1):<\/strong> Die Callers-Caddy-1.0-Migration durchsucht die Musikordner jetzt rekursiv inklusive aller Unterordner (vorher nur die oberste Ebene).<\/li>\n\n\n\n<li><strong>Keine verlorenen Dateien mehr bei gleichen Namen (SqView):<\/strong> Gleichnamige Dateien in verschiedenen Ordnern gingen bisher verloren. Jetzt bleiben beide erhalten; bei mehreren Treffern wird anhand des urspr\u00fcnglichen Pfads die passende Datei gew\u00e4hlt.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.99 \u2014 Migrations-Detaillog und robustere SqView-\u00dcbernahme (2026-06-14)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>App startet nach einem Absturz wieder zuverl\u00e4ssig:<\/strong> St\u00fcrzte Callers Caddy ab, blieb eine interne Sperrdatei zur\u00fcck, die jeden weiteren Start mit der Meldung \u201eCallers Caddy l\u00e4uft bereits&#8220; blockierte \u2014 auch ein Rechner-Neustart half nicht, da die Datei auf der Festplatte verblieb. Die App pr\u00fcft jetzt beim Start, ob die als Sperr-Besitzer eingetragene Programm-Instanz \u00fcberhaupt noch l\u00e4uft, und entfernt verwaiste Sperren automatisch. L\u00e4uft tats\u00e4chlich noch eine Instanz, erscheint die Hinweismeldung wie bisher.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Migrationstool<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Detailliertes Migrationslog:<\/strong> Bei jeder Migration (SqView wie auch Callers Caddy 1.0) wird jetzt im Zielordner eine Logdatei abgelegt (<code>migration_log_&lt;Datum&gt;_&lt;Uhrzeit&gt;.txt<\/code>). Sie protokolliert Schritt f\u00fcr Schritt, was pro Song getan wurde \u2014 Datensatz \u00fcbernommen, Sprungmarken \u00fcbernommen, Lyrics gefunden und eingetragen, MP3 gefunden und verkn\u00fcpft \u2014 und ist auch nach der Migration jederzeit nachlesbar. Die Datei wird laufend geschrieben, sodass auch bei einem Abbruch alles bis dahin erhalten bleibt.<\/li>\n\n\n\n<li><strong>Drei Meldungsstufen:<\/strong> Jeder Schritt wird als <code>DONE<\/code>, <code>WARNING<\/code> oder <code>ERROR<\/code> eingestuft. Am Ende des Logs steht eine Zusammenfassung, summiert nach Kategorien \u2014 auf einen Blick erkennbar, was gelungen ist und was nicht.<\/li>\n\n\n\n<li><strong>Suchbarer Doppel-Schl\u00fcssel (Schweregrad + Thema):<\/strong> Jede Logzeile beginnt mit einem sprachunabh\u00e4ngigen Schl\u00fcssel aus Schweregrad und Thema, z.B. <code>ERROR MUSIC<\/code>, <code>DONE LYRIC<\/code>, <code>WARNING LYRIC<\/code>, <code>DONE LOOP<\/code>. So lassen sich einzelne Themen im Log gezielt per Volltextsuche finden, unabh\u00e4ngig von der Sprache der Beschreibung.<\/li>\n\n\n\n<li><strong>Aufger\u00e4umte Live-Anzeige:<\/strong> W\u00e4hrend der Migration zeigt das Fenster nur noch den Phasen-Fortschritt, alle Warnungen\/Fehler und die Schluss-Zusammenfassung. Die vollst\u00e4ndige Schritt-f\u00fcr-Schritt-Liste landet im Detaillog. Ein neuer Button \u201eDetaillog \u00f6ffnen&#8220; \u00f6ffnet die Logdatei direkt \u2014 auch nach einem Fehlerabbruch.<\/li>\n\n\n\n<li><strong>Fehlende Dateien werden als Fehler erkannt:<\/strong> Ist eine Datei laut Quellsystem vorhanden, wird sie beim Import aber nicht gefunden (MP3 oder Lyrics), erscheint das jetzt als <code>ERROR<\/code> statt unbemerkt zu bleiben. Der bewusste Blind-Import ohne Musik-Ordner bleibt eine Warnung.<\/li>\n\n\n\n<li><strong>Lyrics-Zuordnungen aus SqView werden bevorzugt:<\/strong> Explizite Song-zu-Lyrics-Verkn\u00fcpfungen aus SqView (marry-Tabelle) werden jetzt zuerst ausgewertet, bevor auf die namensbasierte Suche zur\u00fcckgegriffen wird. Damit bleiben manuell gepflegte Zuordnungen erhalten.<\/li>\n\n\n\n<li><strong>Logsprache folgt der gew\u00e4hlten Sprache:<\/strong> Das Detaillog wird in Deutsch oder Englisch geschrieben \u2014 je nach gew\u00e4hlter Sprache. Die Stufen-Kennungen <code>DONE<\/code>\/<code>WARNING<\/code>\/<code>ERROR<\/code> bleiben sprachunabh\u00e4ngig, damit das Log durchsuchbar bleibt.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">SqView-Import: vollst\u00e4ndigere und korrekte \u00dcbernahme<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Gesamte Song-Bibliothek wird \u00fcbernommen:<\/strong> Bisher kamen nur Songs aus den aktuellen Listen und der Abspielhistorie an (~1000). Jetzt wird die komplette Song-Bibliothek der Quelle gehoben \u2014 inklusive aller Songs mit gesetzten Loop-Markern, die in keiner aktuellen Liste mehr standen. Songs, deren Audiodatei nicht mehr auffindbar ist, werden als Blind-Eintrag mit Fehler-Hinweis protokolliert und lassen sich sp\u00e4ter per Datei-Import aktivieren.<\/li>\n\n\n\n<li><strong>Korrekte Patter\/Singing-Einstufung:<\/strong> Die Einstufung als Patter, Singing oder beides hing vorher allein am Ordnernamen \u2014 dabei wurden ganze Ordner (z.B. \u201eSinging Calls&#8220;) falsch als Patter erkannt. Neue Regel: Sind Loop-Marker gesetzt, ist es ein Patter; ist ein Lyric vorhanden, wird der Singing-Marker gesetzt; der Ordnerpfad z\u00e4hlt nur noch als Indiz. Songs, die beides erf\u00fcllen, z\u00e4hlen automatisch zu Patter UND Singing. Ohne jedes Signal wird ein Song als Singing eingestuft.<\/li>\n\n\n\n<li><strong>Apostrophe in Titeln werden bereinigt:<\/strong> Songtitel mit Apostroph (z.B. \u201eAin&#8217;t Misbehaving&#8220;) wurden aus der Quelle mit einem Platzhalter-Sonderzeichen \u00fcbernommen. Diese werden beim Import jetzt automatisch in einen normalen Apostroph zur\u00fcckgewandelt. Das Auffinden der zugeh\u00f6rigen Audio- und Lyrics-Dateien funktioniert unabh\u00e4ngig von der Schreibweise.<\/li>\n\n\n\n<li><strong>Lyrics-Zuordnung aus der Quelle bevorzugt:<\/strong> Explizite Song-zu-Lyrics-Verkn\u00fcpfungen der Quelle werden zuerst genutzt; nur wenn keine vorliegt, greift die namensbasierte Suche.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.98 \u2014 Lyrics direkt in der App bearbeiten (2026-06-08)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Funktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Lyrics-Editor im Lyrics-Dock:<\/strong> Die Lyrics k\u00f6nnen jetzt direkt in Callers Caddy bearbeitet werden \u2014 keine externe Word- oder Editor-Sitzung mehr n\u00f6tig. Ein neuer Stift-Button (\u270e) rechts in der Lyrics-Toolbar schaltet zwischen Anzeige- und Bearbeitungsmodus um. Alternativ aktiviert ein Doppelklick auf den Lyric-Text den Bearbeitungsmodus.<\/li>\n\n\n\n<li><strong>Volle Rich-Text-Bearbeitung:<\/strong> Im Edit-Modus erscheint eine zweite Toolbar mit allen wichtigen Formatierungen \u2014 Absatz-Format (Normal \/ \u00dcberschrift 1\u20133), Schriftgr\u00f6\u00dfe (6\u201396 pt), Fett, Kursiv, Unterstrichen, Schriftfarbe und Hintergrundfarbe (Markierung). Damit lassen sich Tag-, Break- und Closer-Zeilen so hervorheben wie man es im Live-Betrieb sehen m\u00f6chte.<\/li>\n\n\n\n<li><strong>HTML als einheitliches Zielformat:<\/strong> Beim Speichern wird die Datei immer als HTML abgelegt. HTML deckt alle Anforderungen (\u00dcberschriften, Auszeichnungen, Schriftgr\u00f6\u00dfen, Farben, Hintergrundfarben) verlustfrei ab und ist von jedem Browser oder Editor weiter bearbeitbar.<\/li>\n\n\n\n<li><strong>Original-Dateien bleiben unangetastet:<\/strong> RTF- und TXT-Lyrics werden beim Bearbeiten NIE \u00fcberschrieben. Stattdessen legt Callers Caddy eine neue <code>.html<\/code>-Datei neben das Original und zieht den <code>lyrics_file<\/code>-Eintrag des Songs auf die neue Datei um. Das Original bleibt als Sicherung im Lyrics-Ordner liegen. Eine kurze Info-Meldung weist nach dem ersten Speichern darauf hin.<\/li>\n\n\n\n<li><strong>HTML-Originale werden mit Backup \u00fcberschrieben:<\/strong> Beim ersten Speichern einer HTML-Lyrics-Datei wird automatisch eine <code>.bak<\/code>-Sicherung der Originaldatei daneben angelegt \u2014 falls man die alte Fassung sp\u00e4ter noch braucht.<\/li>\n\n\n\n<li><strong>Tastatur-Shortcuts:<\/strong> <code>Strg+S<\/code> speichert und verl\u00e4sst den Edit-Modus, <code>Esc<\/code> verwirft die \u00c4nderungen (mit R\u00fcckfrage, falls etwas ge\u00e4ndert wurde).<\/li>\n\n\n\n<li><strong>Sicherheit beim Songwechsel:<\/strong> Wer den Song wechselt w\u00e4hrend Lyrics noch ungespeichert bearbeitet werden, bekommt eine R\u00fcckfrage \u201e\u00c4nderungen verwerfen?&#8220; \u2014 versehentlicher Verlust wird damit ausgeschlossen.<\/li>\n\n\n\n<li><strong>Schriftgr\u00f6\u00dfe wirkt sofort sichtbar:<\/strong> Wer im Edit-Modus die Schriftgr\u00f6\u00dfe \u00fcber das Spinbox-Feld \u00e4ndert (Pfeiltasten oder Eingabe), sieht die \u00c4nderung live im Text. Ohne Selektion wirkt die neue Gr\u00f6\u00dfe auf das ganze Dokument, mit Selektion nur auf den markierten Bereich.<\/li>\n\n\n\n<li><strong>Per-Wort-Schriftgr\u00f6\u00dfen bleiben in der Anzeige erhalten:<\/strong> Ein bewusst gr\u00f6\u00dfer gesetztes Wort (z.B. eine besonders zu betonende Stelle im Lyric) bleibt nach dem Speichern auch in der Lyrics-Anzeige sichtbar gr\u00f6\u00dfer. Vorher wurden Schriftgr\u00f6\u00dfen-Angaben beim Anzeigen vereinheitlicht \u2014 jetzt nicht mehr.<\/li>\n\n\n\n<li><strong>Zoom und Auto-Width skalieren das ganze Dokument proportional:<\/strong> Auch wenn einzelne W\u00f6rter unterschiedliche Schriftgr\u00f6\u00dfen haben, skalieren Zoom-Buttons und Auto-Width das gesamte Dokument verh\u00e4ltnistreu \u2014 der Gr\u00f6\u00dfenunterschied zwischen markierten und normalen Stellen bleibt bei jeder Anzeige-Gr\u00f6\u00dfe erhalten.<\/li>\n\n\n\n<li><strong>Auto-Modi sinnvoll im Edit-Mode:<\/strong> Auto-Scroll und Auto-Size sind w\u00e4hrend des Bearbeitens deaktiviert (w\u00fcrden den Cursor verschieben bzw. die Schrift beim Tippen springen lassen). Auto-Width und manueller Zoom bleiben verf\u00fcgbar \u2014 sie \u00e4ndern nur die Anzeige, nicht die gespeicherten Gr\u00f6\u00dfen. Nach dem Speichern werden alle Modi wieder aktiv.<\/li>\n\n\n\n<li><strong>Icons in allen Skins:<\/strong> Die neuen Toolbar-Buttons (Stift, Speichern, B\/I\/U, Schrift-\/Hintergrundfarbe, Verwerfen) liegen als SVG-Icons in jedem der vier mitgelieferten Skins (Default, Elegant, Light, Win11). Die Icons folgen dem etablierten Skin-Pattern und passen sich an das gew\u00e4hlte Theme an.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.97 \u2014 Pitch-Wechsel ohne Leiern, eigener Timer-Sound und Label im Player (2026-06-03)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Funktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Eigener Sound bei Timer-\u00dcberzug (BL-137):<\/strong> Statt des System-Pieps kann beim \u00dcberschreiten der Pattern-\/Singing-Zeit jetzt eine MP3 oder WAV abgespielt werden \u2014 z.B. das ber\u00fchmte Esel-Ger\u00e4usch eines Caller-Kollegen. Der Sound wird in den laufenden Audio-Stream eingemischt (gleicher Output, gleiches Ger\u00e4t, kein zweiter Stream) und st\u00f6rt die Musik nicht. Konfiguriert \u00fcber Einstellungen \u2192 Audio: \u201eHinweis-Sound (Timer-\u00dcberzug)&#8220; mit Datei-Picker und eigenem Lautst\u00e4rke-Schieberegler. Wenn kein Pfad gesetzt ist, bleibt der bisherige Doppel-Beep aktiv. Alternativ kann der Sound auch pro Rule individuell mitgegeben werden (Parameter <code>sound<\/code> in der <code>system_ping<\/code>-Aktion) \u2014 damit lassen sich Pattern und Singing mit unterschiedlichen T\u00f6nen unterscheiden.<\/li>\n\n\n\n<li><strong>Neue Rule-Aktion \u201eSound abspielen&#8220;:<\/strong> Im Rule-Editor erscheint in der Gruppe \u201eInfo &amp; Warnings&#8220; direkt \u00fcber \u201eSystem Ping (Beep)&#8220; die neue Aktion. \u00dcber einen Datei-Picker w\u00e4hlt man eine Audiodatei, die Lautst\u00e4rke ist pro Rule einstellbar. Die Datei wird in den laufenden Stream eingemischt \u2014 kein zweiter Kanal, kein Aussetzer im Hauptsong.<\/li>\n\n\n\n<li><strong>Plattenlabel im Player (BL-138):<\/strong> Das Plattenlabel des aktuell gespielten Songs (z.B. \u201eDGR 014&#8243;) wird jetzt rechts oben im Player direkt \u00fcber dem Status angezeigt \u2014 gleiche Schrift, kein Zusatzabstand. Wird ausgeblendet wenn kein Label gepflegt ist.<\/li>\n\n\n\n<li><strong>Rules im Loop-Finder-Vorh\u00f6ren pausiert:<\/strong> W\u00e4hrend des Vorh\u00f6rens im Loop-Finder (Audition) werden alle Rules komplett deaktiviert. Damit springt Auto-Advance oder andere song_stopped-Rules beim Ende der Audition nicht mehr an. Nach dem Beenden der Audition laufen Rules wieder normal. Technisch \u00fcber eine zentrale suspend\/resume-Mechanik in der Rule-Engine gel\u00f6st \u2014 wiederverwendbar f\u00fcr zuk\u00fcnftige Vorh\u00f6r-Funktionen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen f\u00fcr den Live-Betrieb<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pitch-Slider reagiert jetzt sofort:<\/strong> Wer den Pitch-Slider w\u00e4hrend der Wiedergabe verschoben hat, h\u00f6rte die neue Tonh\u00f6he bisher erst nach mehreren Sekunden \u2014 und in der \u00dcbergangsphase \u201eleierte&#8220; das Tempo h\u00f6rbar (ca. 20 % Schwankung \u00fcber 4 Sekunden). Die Audio-Engine setzt das Resampling jetzt hinter den WSOLA-Stretcher (SoundTouch-Architektur f\u00fcr rate &gt; 1), womit Pitch-\u00c4nderungen binnen weniger Millisekunden am Lautsprecher h\u00f6rbar sind und das Tempo durch den Wechsel praktisch nicht mehr aus dem Tritt kommt. Tempo-Slider (<code>set_today_tempo<\/code>, <code>set_tempo<\/code>) bleibt unver\u00e4ndert nach AR-021-Pattern. Messtechnisch: Tr\u00e4ger-Einschwingzeit von &gt;3000 ms auf 6 ms, RMS-Abweichung von 188 Hz auf 0,77 Hz.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Unter der Haube<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PitchShifter komplett \u00fcberarbeitet:<\/strong> Statt blockweisem FFT-Resampling jetzt ein stateful Cubic-Hermite-Interpolator (Catmull-Rom, 4-Punkt-Kernel) mit fraktionaler Lese-Position und 3-Sample-Tail \u00fcber Aufrufe hinweg. Pitch-Wechsel zur Laufzeit erfolgen ohne Reset\/Flush, nur der Ratio-Parameter wird gewechselt \u2014 analog zu SoundTouch&#8217;s RateTransposer.<\/li>\n\n\n\n<li><strong>Pipeline-Reihenfolge:<\/strong> Stretcher bekommt jetzt Original-Audio (vorher: pre-resampletes Audio im 5-Sekunden-Puffer, das beim Pitch-Wechsel mit dem neuen Tempo-Parameter kollidierte). Resampling l\u00e4uft im Audio-Callback hinter <code>stretcher.retrieve<\/code>, mit Carry-Buffer f\u00fcr variable Output-L\u00e4ngen.<\/li>\n\n\n\n<li><strong>Diagnose-Capture:<\/strong> Neue Engine-Methoden <code>start_output_capture<\/code> \/ <code>stop_output_capture<\/code> f\u00fcr Diagnose-Tools. Im Normalbetrieb ein einziger <code>is None<\/code>-Check pro Callback, keine Performance-Auswirkung. Test-Tools in <code>1_Source\/src\/tools\/pitch_transition_test.py<\/code> und <code>pitch_transition_analyze.py<\/code> f\u00fcr AM-modulierte Sinus-Messungen (Tr\u00e4ger zeigt Pitch, H\u00fcllkurve zeigt Tempo via Nulldurchgang-Analyse).<\/li>\n\n\n\n<li><strong>Rule-Engine Suspend\/Resume:<\/strong> Neue API <code>rule_engine.suspend(reason)<\/code> \/ <code>rule_engine.resume(reason)<\/code> und Kontext-Manager <code>with rule_engine.suspended(\"xy\"):<\/code>. Counter-basiert, verschachtelbar \u2014 mehrere gleichzeitige Suspend-Aufrufe heben sich erst dann auf wenn alle resume() gerufen wurden. W\u00e4hrend des Suspends werden alle Trigger (au\u00dfer <code>play_timer<\/code>) im rules.log als <code>SUSPENDED<\/code> protokolliert.<\/li>\n\n\n\n<li><strong>Einstellungen-Dialog (BL-129): neue Felder erscheinen automatisch.<\/strong> Der Dialog enumeriert jetzt nicht nur vorhandene INI-Keys, sondern auch alle Keys aus <code>SETTINGS_META<\/code> \u2014 auch wenn sie noch nie geschrieben wurden. Neuer Widget-Typ <code>file<\/code> f\u00fcr Datei-Picker (mit konfigurierbarem Audio-Filter).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.96 \u2014 Sequenzen verwalten und vereinheitlichter Import (2026-06-01)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Funktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Universeller Sequenz-Import (BL-098):<\/strong> Ein neuer Men\u00fcpunkt \u201eSequenzen \u2192 Sequenzen importieren\u2026&#8220; ersetzt die vier bisherigen Import-Wege (MDB, JSON, CSDS, Freitext). Du w\u00e4hlst einfach die Datei, der Dialog erkennt das Format automatisch (Datei-Endung + Inhalts-Stichprobe), zeigt eine Live-Vorschau der ersten drei Sequenzen und meldet, wie viele S\u00e4tze erkannt wurden. Format kann bei Bedarf manuell \u00fcberschrieben werden. Multi-Datei-Auswahl funktioniert f\u00fcr JSON, CSDS und Freitext \u2014 alle Dateien werden in einem Rutsch verarbeitet. Die alten Einzeleintr\u00e4ge sind aus dem Men\u00fc verschwunden; die zugrunde liegenden Routinen bleiben bis 1.8.2026 als Sicherheitsnetz erhalten (BL-135).<\/li>\n\n\n\n<li><strong>Freitext-Format mit drei Schreibweisen:<\/strong> Der Freitext-Parser versteht jetzt (1) eine Sequenz pro Zeile mit Komma-getrennten Calls, (2) ein Call pro Zeile mit Leerzeile als Trenner zwischen Sequenzen, (3) wie 2 aber mit <code>,<\/code> oder <code>;<\/code> am Zeilenende. Zus\u00e4tzlich werden Ceder-Webseiten-Header (<code>... ID=&lt;nummer&gt; Print<\/code>) als Sequenz-Trenner erkannt \u2014 du kannst die Choreo-Datenbank-Sammlungen also direkt copy-pasten und importieren.<\/li>\n\n\n\n<li><strong>Bulk-Werte oder aus der Datei (Typ + Schwierigkeit):<\/strong> Bei JSON- und CSDS-Importen, die Typ und Schwierigkeit pro Sequenz mitliefern, kannst du pro Feld w\u00e4hlen: entweder der im Dialog gesetzte Bulk-Wert f\u00fcr alle Sequenzen, oder die Werte aus der Datei (mit Bulk als Fallback wenn die Datei f\u00fcr eine einzelne Sequenz nichts mitbringt).<\/li>\n\n\n\n<li><strong>Duplikat-Erkennung beim Import:<\/strong> Vor dem Schreiben pr\u00fcft der Importer per 15-Feld-Vergleich, ob die Sequenz schon in der Datenbank steht oder zweimal in den ausgew\u00e4hlten Dateien vorkommt. Default-m\u00e4\u00dfig aktiviert; die Status-Zeile meldet \u201eX erkannt \u2014 Y neu, Z Duplikate&#8220;. Spart das nachtr\u00e4gliche Aufr\u00e4umen \u00fcber den Deduplikat-Dialog.<\/li>\n\n\n\n<li><strong>Sequenzen l\u00f6schen (BL-136):<\/strong> Rechtsklick auf eine Sequenz in der Sequenz-Liste \u2192 \u201eL\u00f6schen&#8220;. Mehrere markieren (Strg-\/Shift-Klick) und gemeinsam l\u00f6schen geht ebenfalls \u2014 entweder per Rechtsklick-Men\u00fc oder \u00fcber den neuen \u201eL\u00f6schen&#8220;-Button unter der Tabelle. Im Detail-Fenster (SequenzView) gibt es zus\u00e4tzlich einen L\u00f6schen-Button in der Navigations-Leiste; nach dem L\u00f6schen r\u00fcckt automatisch die n\u00e4chste Sequenz aus der gefilterten Liste nach. Jede L\u00f6schung fragt vor dem Vollzug nach, mit Singular- oder Plural-Text je nach Auswahl.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen f\u00fcr den Live-Betrieb<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Lyrics passen sich nach Songwechsel automatisch an:<\/strong> Wer \u201eAuto-Gr\u00f6\u00dfe&#8220; oder \u201eAuto-Breite&#8220; im Lyrics-Fenster aktiv hat, sah bisher beim Songwechsel die neue Datei nur in Basis-Schriftgr\u00f6\u00dfe \u2014 der Refit fand schlicht nicht statt. Beide Modi sind jetzt persistente Schalter, die sich gegenseitig ausschlie\u00dfen, und werden bei jedem neuen Song erneut ausgel\u00f6st. Der Refit-Zeitpunkt h\u00e4ngt ab sofort am tats\u00e4chlichen Layout-Ende des Textbrowsers (statt an einer festen 50-ms-Verz\u00f6gerung), damit auch langsam ladende HTML- oder RTF-Dateien sauber skaliert werden.<\/li>\n\n\n\n<li><strong>Shift-\/Strg-Klick \u00f6ffnet den SequenzView nicht mehr:<\/strong> Wer in der Sequenz-Liste mit Mehrfach-Klick eine Auswahl aufbaut, bekam bei jedem Klick die Detail-Ansicht neu aufgerufen \u2014 st\u00f6rte beim Markieren. Jetzt: nur der einfache Klick (ohne Modifier) wechselt das Detail-Fenster.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.95 \u2014 Bessere Diagnose bei Audio-Problemen (2026-06-01)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Geladene Songs im Perf-Log:<\/strong> Bei jedem Song-Wechsel wird jetzt eine Diagnose-Zeile mit Dateinamen, vollem Pfad, Samplerate, Kan\u00e4len und Dauer geschrieben. Damit l\u00e4sst sich im Problemfall (Aussetzer, Klangst\u00f6rung, Stream-Reopen) sofort nachvollziehen, welche Datei genau in dem Moment lief \u2014 vorher musste man das umst\u00e4ndlich aus der Spielhistorie rekonstruieren. F\u00fcr den Live-Betrieb komplett unsichtbar; sp\u00fcrbar nur bei sp\u00e4terer Fehlersuche.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.94 \u2014 Tempo- und Pitch-Wechsel ohne Ruckler (2026-05-31)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen f\u00fcr den Live-Betrieb<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tempo-Wechsel klingen jetzt sauber durch (AR-021).<\/strong> Wer am Tempo- oder Pitch-Regler dreht, h\u00f6rt keinen kurzen Aussetzer mehr und das Lied bleibt exakt an der Stelle, an der es gerade war. Besonders relevant f\u00fcr \u201eHotHash&#8220;-Situationen, in denen das Tempo schrittweise erh\u00f6ht wird \u2014 jeder einzelne Klick f\u00fchrt jetzt zu einem nahtlosen \u00dcbergang statt zu einem h\u00f6rbaren Sprung. Gilt f\u00fcr alle drei Eingabewege: Song-Tempo (das in der DB gespeichert wird), Heutiges Tempo (Session-Faktor) und Pitch.<\/li>\n\n\n\n<li><strong>Etwas Reaktions-Latenz beim Tempo-Wechsel:<\/strong> Bis das neue Tempo h\u00f6rbar einsetzt, l\u00e4uft noch bis zu eine knappe Sekunde im alten Tempo weiter. Das ist der Audio-Vorrats-Puffer, der seit v0.93 f\u00fcr die generelle Aussetzer-Freiheit zust\u00e4ndig ist \u2014 wir lassen ihn bewusst in Ruhe, weil jeder Eingriff genau die Ruckler erzeugen w\u00fcrde, die wir vermeiden wollen. In der Praxis hei\u00dft das: zwischen zwei Tempo-Klicks lieber ein kleines bisschen Pause lassen, dann h\u00f6rt man jeden Schritt sauber.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.93 \u2014 WSOLA-Stretcher entkoppelt: Knistern bei niedriger Latenz behoben (2026-05-31)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Performance \/ Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>WSOLA-Passthrough bei Tempo 1.0 (AR-020 Fix A):<\/strong> Bisher lief die teure Coarse-to-Fine-Kreuzkorrelation in <code>time_stretcher.py<\/code> <strong>auch<\/strong> wenn der Tempo-Regler auf 1.0 stand. Bei COLA-konformen Hann-Fenstern mit 50 % Overlap und ana_hop == syn_hop ist die nominale Position aber mathematisch bereits exakt \u2014 die Korrelation liefert sowieso nur das nominale Ergebnis zur\u00fcck. Auf einem Celeron N3450 kostete diese unn\u00f6tige Suche bis zu 15 ms Lock-Hold pro Hop und wurde unter WDM-KS bei 11 ms Hardware-Latenz als Knistern h\u00f6rbar. Jetzt: bei Tempo == 1.0 wird die Korrelation komplett \u00fcbersprungen.<\/li>\n\n\n\n<li><strong>PREPROCESS_OUTPUT_SECONDS 0.25 \u2192 1.0 (AR-020 Fix B):<\/strong> Der Stretcher-Output-Buffer wird jetzt auf 1 s statt 250 ms Soll-Stand gehalten. Damit werden auch maximale Hop-Berechnungs-Spitzen (z. B. bei Tempo-Drag) absorbiert, bevor sie den Hardware-Buffer treffen k\u00f6nnen. Vorher: Buffer pendelte 232\u2013325 ms mit periodischem Dip auf 209 ms \u2192 23 ms Reserve unter WDM-KS. Nachher: Buffer pendelt 998\u20131091 ms \u2192 ~1 s Reserve \u00fcber alle Hostapis.<\/li>\n\n\n\n<li><strong>Stretcher mit zwei Locks (AR-020 Fix C):<\/strong> <code>time_stretcher.py<\/code> hatte einen einzigen Lock, den <code>preprocess()<\/code> w\u00e4hrend der gesamten teuren Hop-Berechnung gehalten hat. Der Audio-Callback wartete im <code>retrieve()<\/code> auf denselben Lock \u2014 selbst wenn er nur Output-Frames lesen wollte. Jetzt sch\u00fctzt ein zweiter, schmaler <code>_out_lock<\/code> ausschlie\u00dflich den Output-Buffer; <code>retrieve()<\/code> wartet h\u00f6chstens auf das kurze Append eines fertigen Hops, nicht mehr auf die WSOLA-Berechnung selbst.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Diagnose<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Stretcher-Stats-Zeile alle 5 s:<\/strong> Neue <code>[Diag] Stretcher-Stats<\/code>-Zeile direkt unter jedem <code>[AudioBuf]<\/code>-Eintrag im Perf-Log. Format: <code>hops=N passthrough=N (X%) correlation=N lock_hold_ms avg=X.XX max=X.XX<\/code>. Zeigt damit auf einen Blick: ob Fix A greift (Passthrough-Anteil), wie teuer die Hop-Berechnung tats\u00e4chlich ist (Lock-Hold-Zeiten), und wann der User am Tempo war (Correlation &gt; 0).<\/li>\n\n\n\n<li><strong>Lock-Hold-Messung:<\/strong> Jeder Hop wird in <code>time_stretcher.preprocess()<\/code> via <code>time.monotonic_ns()<\/code> umrahmt \u2014 die Statistik liefert Avg + Max pro 5-s-Fenster.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hintergrund<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Thorstens v0.92-Trace 2026-05-31 (perf_24\u201327) zeigte: WDM-KS messtechnisch perfekt (0 XRuns, hw_default=44100 Hz, distinct=1 im Frame-Histogramm), aber h\u00f6rbares Knistern wie Kabelbruch. AR-020 Mechanismus (a) und (c) damit definitiv widerlegt. Code-Review im Stretcher: <code>min10s=209 ms<\/code> exakt konstant entspricht ~2 Callback-Blocks unter dem 250-ms-Soll \u2192 der Feeder konnte einzelne Ticks nicht rechtzeitig liefern, weil der einzige Lock von der teuren Hop-Berechnung gehalten wurde. Die drei Fixes adressieren genau diese Engstelle.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.92 \u2014 Audio-Diagnose: Sample-Rate-Mismatch und Callback-Frame-Histogramm (2026-05-30)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Logs &amp; Diagnose<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Hardware-Sample-Rate im Stream-Diag-Log (AR-020 T1):<\/strong> Sowohl <code>[Diag] Stream-Init Versuch<\/code> als auch <code>[Diag] Stream gestartet<\/code> zeigen jetzt zus\u00e4tzlich <code>hw_default=XHz<\/code> \u2014 die native Sample-Rate des Audio-Devices. Wenn das nicht zu unserer angeforderten Rate (44100 Hz) passt, \u00fcbernimmt der Treiber Resampling \u2014 auf manchen Hostapi\/Codec-Kombinationen (WDM-KS + Realtek HD ist bekannt) ist die Qualit\u00e4t schlecht und als \u201ekomischer Klang&#8220;\/\u201eGeschwindigkeitsfluktuation&#8220; h\u00f6rbar, ohne dass es zu Buffer-Underruns kommt. Wenn <code>hw_default \u2260 angeforderte SR<\/code>, erscheint zus\u00e4tzlich ein deutlicher <code>\u26a0 SR-MISMATCH (wir fordern NHz)<\/code>-Marker direkt in der Versuchs-Zeile.<\/li>\n\n\n\n<li><strong>Callback-Frame-Count-Histogramm (AR-020 T1):<\/strong> Pro Stream werden die ersten 200 Aufrufe des PortAudio-Callbacks gez\u00e4hlt und einmalig als kompaktes Histogramm geloggt: <code>[Diag] Callback-frames-Histogramm (erste 200): min=1024 max=1024 distinct=1 | top: 1024\u00d7200 (100%)<\/code>. Liefert der Treiber konstante Block-Gr\u00f6\u00dfen, steht <code>distinct=1<\/code> \u2014 schwankt er (Verdacht WDM-KS), sieht man die Verteilung sofort. Das Sampling ist ein billiger <code>list.append<\/code> pro Callback, kein Lock, kein I\/O.<\/li>\n\n\n\n<li><strong>Hintergrund:<\/strong> Thorstens Test 2026-05-30 (perf_log_22, T-Lap, WDM-KS) zeigte 4 min <code>xRuns=0<\/code> bei perfektem Buffer \u2014 trotzdem h\u00f6rbare Pitch-Wackler und Vinyl-artige St\u00f6rger\u00e4usche. Der direkt anschlie\u00dfende MME-Test (perf_log_23) klang sauber. Die neuen zwei Diag-Zeilen kl\u00e4ren in einem einzigen Trace, ob Sample-Rate-Mismatch (Mechanismus a) oder Frame-Count-Schwankung (Mechanismus c) die Ursache ist.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.91 \u2014 Fade-Out-Stottern behoben, neuer logs\/-Ordner (2026-05-30)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Performance \/ Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Fade-Out vektorisiert (AR-018):<\/strong> Der Fade-Out-Block im PortAudio-Callback (<code>audio_engine.py<\/code>) enthielt eine Python-<code>for<\/code>-Schleife \u00fcber 1024 Samples pro Audio-Block. Auf schwacher Hardware (Thorstens Celeron N3450) verursachte das h\u00f6rbares Stottern beim Fade-Out, weil ~4\u201310 % der Block-Zeit nur f\u00fcr die Fade-Logik draufgingen und der GIL die ganze Schleife lang gehalten wurde. Ersetzt durch NumPy-Array-Multiplikation (1 Aufruf statt 1024 Iterationen). Faktor 100\u2013500\u00d7 Speedup, Fade-Out l\u00e4uft jetzt glatt auch auf schwacher CPU.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Logs &amp; Diagnose<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Diagnose-Center (Hilfe \u2192 Diagnose-Center\u2026):<\/strong> Neues Fenster mit eingebauten Tests, das dem Entwickler bei Aussetzer-Problemen die n\u00f6tigen Daten liefert \u2014 ohne dass du externe Tools installieren musst. Jeder Test erkl\u00e4rt vorher in Klartext was er misst und was du tun sollst. Verf\u00fcgbare Tests:<\/li>\n\n\n\n<li><strong>A \u2014 System-Snapshot:<\/strong> Eckdaten Windows\/CPU\/RAM\/Audio-Ger\u00e4te\/Backends, Callers-Caddy-Version, INI-Inhalt.<\/li>\n\n\n\n<li><strong>D \u2014 QTimer-Inventur:<\/strong> listet alle aktiven Timer im Programm \u2014 hilft beim Aufsp\u00fcren periodischer Aussetzer.<\/li>\n\n\n\n<li><strong>F \u2014 Externe-Last-Sampling (60 s):<\/strong> pr\u00fcft welche anderen Programme w\u00e4hrend der Wiedergabe CPU brauchen (Antivirus, Cloud-Sync, Treiber-Services).<\/li>\n\n\n\n<li><strong>G \u2014 Stall-Sentinel:<\/strong> zeigt Stand der dauerhaften Hintergrund-\u00dcberwachung von Main-Thread-Blockaden w\u00e4hrend der Wiedergabe.<\/li>\n\n\n\n<li><strong>H \u2014 Bundle \u201eSenden an Entwickler&#8220;:<\/strong> packt die letzten Logs in eine ZIP zum Mailen.<\/li>\n\n\n\n<li><strong>B\/C\/E \u2014 Audio-Tests (in Vorbereitung):<\/strong> Stille-Wiedergabe, Hostapi-Vergleich, Fade-Out-Stress kommen mit v0.92.<\/li>\n\n\n\n<li><strong>Zentraler logs\/-Ordner:<\/strong> Alle Logs landen jetzt in <code>&lt;app_dir&gt;\/logs\/<\/code>. Damit bleibt das Hauptverzeichnis aufger\u00e4umt, und Diagnose-Daten sind an <em>einer<\/em> Stelle:<\/li>\n\n\n\n<li><code>logs\/perf\/perf_YYYY-MM-DD_HH-MM-SS.txt<\/code> \u2014 Perflog mit Zeitstempel pro Sitzung (vorher fester Name <code>perf_log.txt<\/code>, jeder Start \u00fcberschrieb den letzten). Automatische Rotation: nur die j\u00fcngsten 20 Sitzungen werden behalten.<\/li>\n\n\n\n<li><code>logs\/crashes\/crash_*.log<\/code> \u2014 Crash-Logs (vorher im Root)<\/li>\n\n\n\n<li><code>logs\/rules.log<\/code> \u2014 Rules-Engine-Log (vorher unter <code>rules\/<\/code>, dort liegen jetzt nur noch die User-Rules-JSONs)<\/li>\n\n\n\n<li><code>logs\/system_report.txt<\/code> \u2014 Systembericht (vorher im Root)<\/li>\n\n\n\n<li><strong>Automatische Migration beim ersten Start v0.91:<\/strong> Vorhandene <code>perf_log.txt<\/code>, <code>crash_*.log<\/code>, <code>rules\/rules.log<\/code> und <code>system_report.txt<\/code> werden einmalig in die neue Struktur verschoben.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.90 \u2014 Sequenz-Editor &amp; Sequenz-Limit pro Tanzprogramm (2026-05-27)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Sequenz-Editor (BL-015):<\/strong> Neues Fenster \u201eSequenzen \u2192 Sequenz-Editor\u2026&#8220; zum Erstellen und Bearbeiten von Sequenzen. Kopfbereich mit Typ (Pflichtfeld) und Schwierigkeit (vorbef\u00fcllte, editierbare Dropdowns), darunter ein Eingabefeld mit <strong>einem Call pro Zeile<\/strong>. Buttons: \u201e+ Neu&#8220;, \u201eSpeichern&#8220;, \u201eAuf Duplikate pr\u00fcfen&#8220; (warnt, wenn die Eingabe bereits existiert) und \u201eSchlie\u00dfen&#8220;. Limit von 15 Calls wird live angezeigt und beim Speichern erzwungen. Bekannte Calls werden <strong>gr\u00fcn<\/strong> markiert (gemappt oder exakter Treffer); ein <strong>Doppelklick<\/strong> auf eine nicht-gr\u00fcne Zeile \u00f6ffnet einen schlanken Zuordnungs-Dialog mit durchsuchbarer Call-Auswahl (Matcher-Vorschlag vorausgew\u00e4hlt). Exakte Treffer werden beim Speichern automatisch gemappt, damit das Level berechnet wird. Aus dem SequenzView f\u00fchrt ein \u270e-Button direkt zum Bearbeiten der angezeigten Sequenz. Nach dem Speichern wird die neue Sequenz garantiert sichtbar (Filter-Reset + Auswahl).<\/li>\n\n\n\n<li><strong>Sequenz-Limit pro Tanzprogramm (BL-132):<\/strong> Im Tanzprogramm-Manager kann pro Programm ein \u201eSequenz-Limit&#8220; hinterlegt werden \u2014 ein beliebiger Call aus der Teaching Order (inkl. Programm-Separatoren wie \u201e&#8211; Mainstream &#8211;&#8222;). Beim Programmwechsel (Lokation laden oder manuell im Player) setzt der Sequenzen-Filter automatisch auf diesen Call. Jeder Caller definiert die Grenze einmalig selbst \u2014 wer auf MS wechselt, sieht nur MS-Sequenzen, wer auf A2 wechselt nur A2. Opt-out in Einstellungen \u2192 Sequenzen \u2192 \u201eFilter automatisch auf Tanzprogramm setzen&#8220;.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.89 \u2014 Mausrad-Schutz, Feedback-Suppress, Call-Mapping Bulk-Confirm, Quality\/ERR per Kontextmenue (2026-05-27)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Kontextmenue Quality\/ERR \u00b11 (BL-127):<\/strong> Songliste, Playlist und Statistik-Dock (TOP\/FLOP\/Nie) zeigen im Rechtsklick-Menue vier neue Eintraege: Qualitaet +1\/\u22121 und ERR +1\/\u22121. Jeder Eintrag zeigt den alten und neuen Wert in der Form <code>[5&gt;6]<\/code>. Am Wertebereichs-Rand (Quality 0\/10, ERR 0\/4) wird die jeweilige Aktion deaktiviert. Aenderungen werden sofort in die DB geschrieben; das Song-Daten-Dock synchronisiert sich live, wenn es denselben Song zeigt.<\/li>\n\n\n\n<li><strong>Feedback-Dialog: Session-Suppression:<\/strong> Neue Checkbox \u201eIn dieser Sitzung nicht mehr fragen&#8220; zwischen Notiz-Feld und Buttons. Bei Haken wird das Auto-Feedback-Fenster fuer den Rest der Sitzung unterdrueckt \u2014 unabhaengig davon, ob \u201eUebernehmen&#8220; oder \u201eAbbrechen&#8220; gedrueckt wird. Wirkt sowohl beim manuellen Feedback-Aufruf als auch beim automatischen Popup nach Songende. INI-Standard bleibt unangetastet und greift beim naechsten App-Start wieder.<\/li>\n\n\n\n<li><strong>Call-Mapping: Bulk-Confirm:<\/strong> Im Call-Mapping-Dialog koennen jetzt mehrere Zeilen markiert (Ctrl\/Shift+Klick, Ctrl+A) und per Button \u201eAuswahl bestaetigen&#8220; gemeinsam in die DB geschrieben werden. Quelle wird auf <code>manual<\/code> gesetzt, Tabelle wird automatisch aus der DB neu geladen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Mausrad-Schutz fluechendeckend:<\/strong> Im Song-Daten-Dock, Player (inkl. Volume- und Position-Slider) und im Einstellungen-Dialog ignorieren SpinBoxes, ComboBoxes, DateEdits und Slider Mausrad-Events. Versehentliches Scrollen ueber Feldern aendert keine Werte mehr. Im Einstellungs-Dialog gilt der Schutz fenster-weit \u2014 auch zukuenftig hinzugefuegte Felder sind automatisch geschuetzt.<\/li>\n\n\n\n<li><strong>Menue \u201eAllgemeine Einstellungen&#8220;:<\/strong> Der Einstellungen-Dialog-Aufruf liegt jetzt im Menue \u201eEinstellungen&#8220; (bisher unter \u201eApp&#8220;) und heisst \u201eAllgemeine Einstellungen\u2026&#8220;. Shortcut <code>Strg+,<\/code> bleibt erhalten. Das App-Menue enthaelt nur noch \u201eBeenden&#8220;.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes \/ Diagnose<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Stall-Detektor schweigt im Leerlauf:<\/strong> Der Main-Thread-Stall-Detektor (AR-F) meldet jetzt nur noch Blockaden waehrend ein Song laeuft. Bei Title-Bar-Drag oder Fenster-Resize entstehen durch Windows&#8216; modale Move-Loop scheinbare \u201eBlockaden&#8220;, die mit Audio-Aussetzern nichts zu tun haben \u2014 diese False Positives erscheinen jetzt nicht mehr im Perf-Log.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Aufgeraeumt<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Toten Translation-Key <code>menu_settings<\/code> entfernt (durch <code>menu_general_settings<\/code> ersetzt)<\/li>\n\n\n\n<li>Drei NoScroll-Subklassen im Settings-Dialog entfernt (durch fenster-weiten Event-Filter ersetzt)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.88 \u2014 Audition-Kanal + Einstellungen-Fenster + Anti-Ruckler (2026-05-26)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Feature: Audition-Kanal (BL-074)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Audition-Button<\/strong> im Player: schmaler Button rechts neben Play, liegt optisch \u00fcber Fade Out<\/li>\n\n\n\n<li>Song startet beim Dr\u00fccken von Audition von vorne auf dem <strong>sekund\u00e4ren Ausgang<\/strong> (exklusiv \u2014 kein zweiter Stream)<\/li>\n\n\n\n<li>Kein History-Eintrag bei Audition; Rules werden nicht gefeuert<\/li>\n\n\n\n<li>Stop \/ Play \/ Song-Ende beenden Audition und stellen automatisch den Prim\u00e4rkanal wieder her<\/li>\n\n\n\n<li><strong>Prim\u00e4rer \/ Sekund\u00e4rer Ausgang<\/strong> jetzt getrennte INI-Keys (<code>audio\/primary_device<\/code>, <code>audio\/secondary_device<\/code>) mit eigener Lautst\u00e4rke (<code>audio\/secondary_volume<\/code>, Default 80 %)<\/li>\n\n\n\n<li>Beide Ger\u00e4te-Dropdowns erscheinen im Einstellungen-Dialog (Audio-Sektion)<\/li>\n\n\n\n<li><strong>Migration:<\/strong> <code>audio\/output_device<\/code> \u2192 <code>audio\/primary_device<\/code> l\u00e4uft einmalig automatisch<\/li>\n\n\n\n<li><strong>Bugfix:<\/strong> WASAPI-Fallback-Cache in <code>AudioEngine<\/code> \u2014 wenn ein Ger\u00e4t beim Start auf System-Default zur\u00fcckf\u00e4llt, wird bei jedem Kanal-Wechsel (Audition \u2192 Prim\u00e4r) der Cache-Eintrag genutzt statt WASAPI erneut zu versuchen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Feature: Einstellungen-Fenster (BL-129)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Fenster \u201eEinstellungen\u2026&#8220; im App-Men\u00fc (Shortcut <code>Strg+,<\/code>)<\/li>\n\n\n\n<li>Liest alle relevanten INI-Sektionen generisch aus und stellt sie in Tabs dar<\/li>\n\n\n\n<li>Automatische Widget-Auswahl je nach Wert-Typ: Checkbox, SpinBox, DoubleSpinBox, Pfad-Button, ComboBox, DateEdit, LineEdit<\/li>\n\n\n\n<li><code>SETTINGS_META<\/code>-Registrierungstabelle f\u00fcr bekannte Keys mit Labels, Tooltips, Wertebereichen und ComboBox-Optionen (Skin-Liste, Sprachen)<\/li>\n\n\n\n<li>Tabs: Anzeige, Pfade, Audio, Loop, Player, Playlist, Feedback, Sequenzen, Notizen, Lyrics, Debug, Rules (System)<\/li>\n\n\n\n<li>Buttons: OK \/ Abbrechen \/ \u00dcbernehmen<\/li>\n\n\n\n<li>Hinweis-Dialog wenn neustart-pflichtige Keys ge\u00e4ndert wurden (Skin, Sprache, Debug, Audio-Flags)<\/li>\n\n\n\n<li>Live-Apply wo m\u00f6glich: Zoom (Sequenzen\/Lyrics\/Notizen), Mindest-Lautst\u00e4rke, Loop-Crossfade, Statusleisten-Player, Musikpfade<\/li>\n\n\n\n<li>Ausgeschlossen: <code>[General]<\/code>, <code>[Tutorials]<\/code>, <code>[custom-filter]<\/code>, alle <code>*_dock<\/code>-Sektionen<\/li>\n\n\n\n<li>Neue <code>settings_dialog.py<\/code> \u2014 standalone, kein Aufbl\u00e4hen von main.py<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Anti-Ruckler: Hostapi-Heuristik + Header-Latenz + Playlist-Refresh-Storm (AR-015 \/ AR-002)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>L1 \u2014 WDM-KS-first Heuristik:<\/strong> Beim Erststart (kein gespeichertes Ger\u00e4t) w\u00e4hlt die App automatisch das beste verf\u00fcgbare Audio-Backend: WDM-KS &gt; WASAPI Shared &gt; MME \u2014 DirectSound nie als Default. Hintergrund: Thorstens Hostapi-Matrix-Test 2026-05-26 (10 Sessions auf Celeron N3450) zeigt WDM-KS = 0 Ruckler, MME = 7\u201310, DirectSound = 15\u201325 pro 30-s-Session. Heuristik l\u00e4uft in <code>_setup_audio_device_combo()<\/code>, speichert das gew\u00e4hlte Ger\u00e4t sofort in INI und loggt <code>[Diag] Auto-Device-Heuristik (AR-015 L1)<\/code>.<\/li>\n\n\n\n<li><strong>L2 \u2014 Perf-Header beide Latenzen:<\/strong> <code>[Sys]<\/code>-Header zeigt jetzt <code>Audio-Output (System-Default)<\/code> UND <code>Audio-Output (konfiguriert)<\/code> (wenn verschieden). <code>generate_compact_header(configured_device_index=...)<\/code> nimmt den gespeicherten Device-Index aus INI entgegen. Verhindert die Verwechslung: MME-Default-Latenz 90 ms vs. tats\u00e4chlich aktive WDM-KS-Latenz 11 ms (Befund 5 aus Hostapi-Matrix).<\/li>\n\n\n\n<li><strong>G \u2014 Playlist-Refresh-Storm behoben (AR-002):<\/strong> Neue Methode <code>PlaylistWidget.add_entries_bulk(entries)<\/code> h\u00e4ngt alle Eintr\u00e4ge intern an und ruft <code>refresh_display()<\/code> + <code>_notify_changed()<\/code> exakt einmal auf \u2014 egal wie viele Songs. Auto-Fill nutzt jetzt Bulk-Add statt N\u00d7 <code>add_entry()<\/code>. Vorher: 24\u00d7 <code>refresh_display<\/code> + 24\u00d7 <code>_refresh_playlist_mirror<\/code>; nachher: 1\u00d7 je.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.87 \u2014 Dock-Open-Instrumentierung + Stall-Detektor 100 ms + Audio-Device-Routing-Diagnose (2026-05-25)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Erweitert die Diagnose-Werkzeuge aus 0.86 um zwei gezielte Messpunkte f\u00fcr Audio-Aussetzer-Ursachen, die wir in den Thorsten-Logs (Desktop + Laptop) gesehen aber nicht eingrenzen konnten. Hintergrund und Verdachtsf\u00e4lle dokumentiert in <code>1_Source\/docs\/anti_ruckler_backlog.md<\/code> (Aufgaben J, N).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Perf-Log: Dock-Toggle-Schritte einzeln gestempelt<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>_toggle_dock(...)<\/code> (zentraler Handler f\u00fcr alle Dock-Buttons in der Statusleiste, u. a. Planner, Lyrics, SongData) stempelt jetzt jeden Qt-Schritt einzeln: <code>setFloating(True)<\/code>, <code>show()<\/code>, <code>move()<\/code>, <code>raise_()<\/code>, <code>setFocus()<\/code>, <code>hide()<\/code>. Plus eine <code>TOTAL<\/code>-Zeile.<\/li>\n\n\n\n<li>Label enth\u00e4lt den Dock-Namen, damit Planner\/Lyrics\/etc. unterscheidbar sind.<\/li>\n\n\n\n<li><code>_on_manager_button_clicked<\/code> (Planner-Button) bekommt zus\u00e4tzlich Stempel um den <code>setCurrentIndex(sort)<\/code>-Trigger (l\u00f6st <code>_apply_filter<\/code> aus).<\/li>\n\n\n\n<li>Zielt auf die Beobachtung von Thorstens Laptop (Celeron N3450): Underflow-Burst direkt nach Planner-Klick, mit Main-Thread-Stall von ~950 ms \u2014 bisher ohne sichtbare Ursache im Log. Die bekannte Qt-Falle <code>setFloating(True) ~90 ms<\/code> (siehe CLAUDE.md) skaliert auf schwacher CPU stark.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Stall-Detektor-Schwelle gesenkt: 150 ms \u2192 100 ms<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In Thorstens Logs vom Vormittag traten Underflows teilweise auf, ohne dass der Stall-Detektor (aus 0.86) etwas meldete \u2014 vermutlich weil Blocks zwischen 100\u2013150 ms unter dem alten Cutoff lagen.<\/li>\n\n\n\n<li>Neue Schwelle 100 ms liegt sicher \u00fcber dem normalen Scheduling-Jitter (~80\u2013100 ms), f\u00e4ngt aber die Blocks zuverl\u00e4ssig, die den Python-PortAudio-Callback am GIL-Greifen hindern.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Diagnostische Konsequenz f\u00fcr AR-014<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die Underflows in Thorstens neuesten Logs (Desktop perf_log_8, Laptop perf_log_14) zeigen alle <code>BUFFER GEFUELLT<\/code> (255\u2013325 ms Vorrat). Der Feeder ist nicht das Problem \u2014 der Python-Callback ist es, weil er bei jedem Aufruf den GIL braucht. Diese Version macht den Beleg daf\u00fcr pr\u00e4ziser, indem sie auch kleinere Stalls + Dock-Schritt-Kosten messbar macht.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Audio-Device-Routing \u2014 Versuch \/ Fallback \/ Endergebnis (Nachzug am Abend)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Hintergrund: in einem Nachmittags-Test zeigte das <code>[Diag] Stream gestartet<\/code> immer noch <code>hostapi=MME<\/code>, obwohl Thorsten laut Video im Combo zweifelsfrei einen WASAPI-Eintrag gew\u00e4hlt hatte. Vermutet: stiller Fallback in <code>_ensure_stream<\/code>, weil die <code>try\/except<\/code>-Kette dort bisher die Ursache verschluckt hat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Drei neue <code>[Diag]<\/code>-Zeilen rund um den Stream-Start machen den Weg vom Combo bis zum aktiven Stream nachvollziehbar:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Versuch (UI-seitig)<\/strong> \u2014 <code>_on_audio_device_changed<\/code> loggt jeden Combo-Wechsel:<br><code>[Diag] Audio-Device Wechsel angefordert: idx=\u2026, combo_label='\u2026'<\/code><\/li>\n\n\n\n<li><strong>Versuch (Engine-seitig)<\/strong> \u2014 <code>_ensure_stream<\/code> loggt vor dem ersten Stream-Open:<br><code>[Diag] Stream-Init Versuch: device=\u2026, name='\u2026', hostapi=\u2026, exclusive=\u2026<\/code><\/li>\n\n\n\n<li><strong>Fallback-Pfade<\/strong> \u2014 wenn das Open mit dem User-Device scheitert:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>[Diag] Stream-Init fehlgeschlagen mit device=\u2026 (\u2026) \u2014 Fallback 1 auf gleiches Device ohne extra_settings<\/code><\/li>\n\n\n\n<li><code>[Diag] Stream-Init Fallback 1 ebenfalls fehlgeschlagen (\u2026) \u2014 Fallback 2 auf System-Standard (\u2026). User-Auswahl device=\u2026 wird IGNORIERT!<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Das bestehende <code>[Diag] Stream gestartet<\/code>-Event zeigt weiterhin das <em>tats\u00e4chlich<\/em> aktive Device + Hostapi (also nach Fallback). Reine Diagnose, keine Verhaltens\u00e4nderung am Audio.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.86 \u2014 Anti-Ruckler-Diagnose + MMCSS-Priorit\u00e4t f\u00fcr Audio-Feeder (2026-05-24)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Erweitert die Ursachensuche f\u00fcr Audio-Aussetzer (TIC-0025-Komplex) durch zwei neue Diagnose-Werkzeuge im <code>perf_log.txt<\/code> und einen ersten L\u00f6sungsversuch auf System-Ebene. Hintergrund und Verdachtsf\u00e4lle dokumentiert in <code>1_Source\/docs\/anti_ruckler_backlog.md<\/code>, User-Anleitung in <code>1_Source\/docs\/diagnose_ruckler_user.md<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Audio-Feeder l\u00e4uft mit MMCSS &#8222;Pro Audio&#8220; Priorit\u00e4t (L\u00f6sungsversuch)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Der dedizierte <code>AudioFeeder<\/code>-Thread (seit 0.80) lief bisher mit normaler Windows-Thread-Priorit\u00e4t. PortAudio gibt seinem eigenen Callback-Thread bereits MMCSS, unser Python-Feeder hatte das nicht \u2014 der Windows-Scheduler konnte ihn dadurch hinter UI-Threads zur\u00fcckstellen, selbst wenn der GIL frei war.<\/li>\n\n\n\n<li>Neu: Als allererste Aktion im Feeder-Run-Loop wird <code>AvSetMmThreadCharacteristicsW(\"Pro Audio\")<\/code> via ctypes aufgerufen. Damit steht der Feeder im Scheduler \u00fcber allen UI-Anwendungen.<\/li>\n\n\n\n<li>Per INI abschaltbar: <code>audio\/mmcss_priority=false<\/code> falls Probleme auftreten.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Perf-Log: Wallclock-Zeitstempel auf allen Zeilen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Jede Zeile im <code>perf_log.txt<\/code> (au\u00dfer <code>[Sys]<\/code>-Header) bekommt jetzt einen <code>HH:MM:SS.mmm<\/code>-Stempel vorangestellt. Damit lassen sich Ruckler-Beobachtungen mit Uhrzeit oder einer Video-Aufnahme exakt mit Log-Events korrelieren.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Perf-Log: System-Header beim Start<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim ersten \u00d6ffnen des Perf-Logs wird ein <code>[Sys]<\/code>-Block geschrieben mit: Callers-Caddy-Version, Python\/PySide6\/Qt-Versionen, OS, CPU, RAM, PortAudio-Version, Default-Audio-Output, <strong>aktiver Hostapi<\/strong> (MME\/DirectSound\/WASAPI\/WDM-KS), verf\u00fcgbare Hostapis, Audio-Engine-Konstanten (<code>FEED_AHEAD<\/code>, <code>PREPROCESS<\/code>, <code>BLOCK<\/code>). Macht Logs verschiedener Sitzungen und User vergleichbar.<\/li>\n\n\n\n<li>Kosten: ~90 ms beim Start (nur wenn <code>debug\/performance_logging=true<\/code>); ohne Subprocess-Calls.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Perf-Log: PortAudio-Underflow-Events mit Buffer-Snapshot<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bisher wurden Underflows nur als Z\u00e4hler erfasst (<code>xRuns=N<\/code>). Jetzt schreibt jeder Underflow eine eigene <code>[Diag]<\/code>-Zeile mit Zeitstempel, Buffer-Stand und Diagnose-Hinweis:<\/li>\n\n\n\n<li><code>BUFFER LEER \u2192 Feeder\/GIL-Verdacht<\/code> (unser Code konnte nicht nachf\u00fcllen)<\/li>\n\n\n\n<li><code>BUFFER GEFUELLT \u2192 Treiber\/Hostapi\/DPC-Verdacht<\/code> (PortAudio meldet trotz voller Daten \u2014 z. B. WASAPI-Shared-Glitch oder Treiber-DPC-Stall)<\/li>\n\n\n\n<li>Events werden im Callback in eine Deque gepusht (kein I\/O im Callback selbst) und vom Feeder-Loop ins Log geschrieben.<\/li>\n\n\n\n<li>Beim Stream-Start zus\u00e4tzlich <code>[Diag] Stream gestartet: '&lt;Device&gt;' hostapi=&lt;...&gt; sr=... blocksize=... latency=...<\/code>.<\/li>\n\n\n\n<li>Per INI abschaltbar: <code>audio\/log_underflows=false<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Neue User-Doku<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>1_Source\/docs\/diagnose_ruckler_user.md<\/code> beschreibt f\u00fcr betroffene User in drei Schritten, wie sie Logs sammeln (Perflog aktivieren, LatencyMon, optional Video-Sync). Kann direkt an User mit Ruckler-Berichten weitergeleitet werden.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">WASAPI Exclusive Mode als Opt-in (AR-008)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die <a href=\"docs\/anti_ruckler_backlog.md\">Recherche<\/a> hatte einen dokumentierten Glitch in Windows WASAPI Shared Mode (PortAudio Issue #303) als wahrscheinlichste Ursache f\u00fcr scheinbar zuf\u00e4llige Mini-Aussetzer identifiziert. Diese Version erlaubt User, WASAPI im Exclusive Mode zu nutzen \u2014 das umgeht den Bug komplett.<\/li>\n\n\n\n<li>Im Audio-Device-Selector wird jetzt der <strong>Hostapi pro Ger\u00e4t<\/strong> angezeigt (<code>\"Speakers (WASAPI)\"<\/code>, <code>\"UR22 mkII (ASIO)\"<\/code>). Damit sieht der User direkt, welches Backend Windows nutzt.<\/li>\n\n\n\n<li>Neue <strong>Checkbox &#8222;Exclusive&#8220;<\/strong> in der Statusleiste neben dem Device-Combo. Aktiviert WASAPI Exclusive Mode f\u00fcr das gew\u00e4hlte Ger\u00e4t; bei Init-Fehler automatisch Fallback auf Shared. Wirkt nur bei WASAPI-Ger\u00e4ten \u2014 andere Hostapis (MME, DirectSound, ASIO) ignorieren das Flag.<\/li>\n\n\n\n<li>Tooltip warnt: Exclusive Mode blockiert andere Audio-Programme systemweit (kein YouTube\/Spotify nebenbei).<\/li>\n\n\n\n<li>INI-Schl\u00fcssel: <code>audio\/wasapi_exclusive=true\/false<\/code> (Default off).<\/li>\n\n\n\n<li>Wer ein ASIO-Interface besitzt (z. B. Steinberg UR22 mkII): einfach das ASIO-Ger\u00e4t aus der Liste w\u00e4hlen \u2014 PortAudio routet automatisch \u00fcber den ASIO-Hostapi, ohne zus\u00e4tzliche Schalter.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hauptthread-Stall-Detektor im Perf-Log<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Der bestehende 50 ms <code>_update_all<\/code>-Timer misst jetzt die L\u00fccke zwischen seinen Ticks. Ist die L\u00fccke gr\u00f6\u00dfer als 150 ms, war der UI-Thread blockiert \u2014 z. B. durch eine schwere Python-Operation, die den GIL belegt.<\/li>\n\n\n\n<li>Geloggt als <code>[Diag] Main-Thread blockiert: NNNms (erwartet 50ms) (letzter [Perf]-Event vor XXXms: ...)<\/code>. \u00dcber den Wallclock-Stempel direkt korrelierbar mit Underflow-Events: war kurz vor einem <code>[Diag] PortAudio output_underflow<\/code> ein Main-Thread-Stall, ist GIL-Contention die wahrscheinliche Ursache.<\/li>\n\n\n\n<li>Der angeh\u00e4ngte &#8222;letzter [Perf]-Event&#8220;-Hinweis nennt die zuletzt instrumentierte Operation, die vor dem Stall lief \u2014 gibt sofort den Verd\u00e4chtigen, ohne im Log scrollen zu m\u00fcssen.<\/li>\n\n\n\n<li>Reines Logging, keine Verhaltens\u00e4nderung.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserte AudioBuf-Klassifikation<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Im ersten Live-Test zeigte sich, dass das bisherige <code>\u26a0 KRITISCH<\/code> h\u00e4ufig falsch alarmierte: <code>min10s=0<\/code> tritt bei jedem Tempo\/Pitch-Change auf, weil der Stretcher dabei kurz geflusht wird \u2014 der 5 s Pre-Roll f\u00e4ngt das aber ab, sodass PortAudio keinen Underflow meldet und nichts h\u00f6rbar wird.<\/li>\n\n\n\n<li>Neue Label-Stufen in der <code>[AudioBuf]<\/code>-Zeile:<\/li>\n\n\n\n<li><code>\u26a0 XRUN (+N echter Aussetzer)<\/code> \u2014 der PortAudio-xRun-Counter ist seit dem letzten Sample gestiegen, das ist ein h\u00f6rbarer Aussetzer auf Treiber-Ebene<\/li>\n\n\n\n<li><code>\u25b3 Buffer-Dip (vermutl. Stretcher-Flush, harmlos)<\/code> \u2014 <code>min10s<\/code> war kurz auf 0, aber kein neuer xRun (typisch bei Tempo\/Pitch-Wechsel)<\/li>\n\n\n\n<li><code>\u25b3 niedrig<\/code> \u2014 <code>min10s<\/code> 50\u2013120 ms (Vorwarnung)<\/li>\n\n\n\n<li>Beim Sichten eines Logs reicht damit Suche nach <code>\u26a0 XRUN<\/code> und <code>[Diag] output_underflow<\/code> \u2014 der Rest ist Rauschen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hinweis<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Version enth\u00e4lt ausschlie\u00dflich Diagnose-Verbesserungen plus den MMCSS-Fix-Versuch. Die in der Recherche gefundenen weiteren Hebel (WASAPI-Exclusive\/ASIO-Wahl, Stall-Detektor, Numba\/CFFI) sind im Anti-Ruckler-Backlog erfasst und werden je nach Ergebnis der ersten Test-Runde priorisiert.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">0.85 \u2014 Filter-Header + Kritischer Bugfix Loop-Datenverlust (2026-05-23)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Loop-Werte wurden beim Songliste-Klick fremd\u00fcberschrieben<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Symptom<\/strong>: 33 Songs hatten identische <code>loop_in=0.34<\/code> Werte mit unterschiedlichen <code>loop_out<\/code> (geclustert nach Quell-Song). Original-Loops waren verloren.<\/li>\n\n\n\n<li><strong>Ursache<\/strong>: <code>_save_current_song<\/code> lief in <code>_on_file_loaded<\/code> mit dem <strong>neuen<\/strong> <code>_current_song<\/code>, aber dem Engine-Loop-Snapshot des <strong>alten<\/strong> Songs. Beim Durchklicken durch die Songliste hat jeder neue Song die Loop-Werte des vorherigen geerbt.<\/li>\n\n\n\n<li><strong>Fix (Variante C+ \u2014 Direkt-Persistierung + Dirty-Flags)<\/strong>:<\/li>\n\n\n\n<li>Jede Loop-\u00c4nderung (Set Loop In\/Out, Beat Snap, Clear Loop) schreibt <strong>sofort<\/strong> in die DB \u2014 kein Sammel-Save beim Song-Wechsel mehr.<\/li>\n\n\n\n<li>Tempo und Pitch nutzen ein Dirty-Flag und werden beim Verlassen des Feldes (Enter \/ Fokus-Wechsel) oder vor dem n\u00e4chsten Song-Wechsel persistiert. W\u00e4hrend eines Slider-Drags <strong>kein<\/strong> DB-Write \u2014 sch\u00fctzt den Audio-Buffer.<\/li>\n\n\n\n<li>Snapshot-Mechanismus (<code>_snapshot_loop_values<\/code>, <code>_saved_loop_in\/out<\/code>, <code>on_before_load<\/code>) komplett entfernt.<\/li>\n\n\n\n<li>Neue Helper-Methode <code>_flush_player_values()<\/code> wird an allen Song-Wechsel-Punkten aufgerufen (Songliste, Playlist, Vorh\u00f6ren, Drag&amp;Drop, closeEvent).<\/li>\n\n\n\n<li><strong>DB-Cleanup<\/strong>: 33 betroffene Songs auf <code>loop_in=0, loop_out=0<\/code> zur\u00fcckgesetzt (Loops m\u00fcssen neu eingerichtet werden).<\/li>\n\n\n\n<li><strong>Backups<\/strong>: DB unter <code>2_Test\/callers_caddy.db.backup_20260522_225318<\/code>, Source unter <code>1_Source\/src\/_fallback\/*.bak_loop_fix_20260522_231059<\/code>.<\/li>\n\n\n\n<li><strong>Testplan<\/strong>: <code>5_Tickets\/loop_data_loss_testplan.md<\/code><\/li>\n\n\n\n<li><strong>Folge-Ticket<\/strong>: <a href=\"5_Tickets\/TIC-0027_audio_buffer_underrun_tempo_drag\/ticket.md\">TIC-0027<\/a> \u2014 Audio-Buffer-Underrun beim Tempo-Drag (eigenst\u00e4ndiges Performance-Thema)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: SongFilterBar \u2014 einheitlicher Filter-\/Sortierbereich (BL-101 + BL-121)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neue gemeinsame Komponente <code>SongFilterBar<\/code><\/strong> ersetzt die bisherigen separaten Filter-Bereiche in Songliste und Planner.<\/li>\n\n\n\n<li><strong>Songliste<\/strong> hat jetzt vollst\u00e4ndige Parit\u00e4t mit dem Planner:<\/li>\n\n\n\n<li><strong>Typ-Filter<\/strong>: RadioButtons Alle \/ Patter \/ Singing<\/li>\n\n\n\n<li><strong>Genre-Filter<\/strong>: ComboBox mit allen verf\u00fcgbaren Genres<\/li>\n\n\n\n<li><strong>Sortierung<\/strong>: Alphabetisch \/ Qualit\u00e4t \/ Zuletzt gespielt \/ <strong>Empfehlung<\/strong> (neu)<\/li>\n\n\n\n<li><strong>Custom-Filter<\/strong>: Button zum Laden gespeicherter Playlisten als Vorauswahl (BL-097)<\/li>\n\n\n\n<li><strong>Suchfeld<\/strong>: Live-Filter \u00fcber Titel, Label, Dateiname<\/li>\n\n\n\n<li><strong>Planner<\/strong> bleibt unver\u00e4ndert \u2014 nutzt jetzt ebenfalls <code>SongFilterBar<\/code> intern.<\/li>\n\n\n\n<li>Kein doppelter Code mehr: Filterlogik, Custom-Filter-Dialog, Persistenz und Sortierung leben an einer einzigen Stelle.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Zuf\u00e4lliger Tiebreaker bei Gleichstand (BL-113)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bei <strong>Sortierung nach Qualit\u00e4t<\/strong> und <strong>Sortierung nach Empfehlung<\/strong> werden Songs mit identischem Score nicht mehr immer in DB-Reihenfolge angezeigt, sondern innerhalb der Gleichstands-Gruppe zuf\u00e4llig gereiht.<\/li>\n\n\n\n<li>Neue <strong>\u201eZufall&#8220;-Checkbox<\/strong> neben dem Sort-Dropdown zum Ein-\/Ausschalten \u2014 bei Alphabetisch und Zuletzt gespielt automatisch ausgegraut.<\/li>\n\n\n\n<li>Die Reihenfolge ist <strong>stabil innerhalb einer Session<\/strong> \u2014 kein Neugemischt bei jedem Tastendruck oder Filter-Wechsel.<\/li>\n\n\n\n<li>Alphabetische Sortierung und Zuletzt-gespielt-Sortierung bleiben unver\u00e4ndert deterministisch.<\/li>\n\n\n\n<li>Wirkt \u00fcberall wo <code>SongFilterBar<\/code> verwendet wird: Songliste, Planner-Pool, Auto-Fill.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Statusleiste \u2014 Miniatur-Abspielfortschritt (BL-128)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neues Widget <code>_StatusBarPlayerBar<\/code><\/strong> in der Statusleiste zeigt dauerhaft den Wiedergabefortschritt:<\/li>\n\n\n\n<li>Fortschritts-F\u00fcllung (semi-transparent, Akzentfarbe aus Skin)<\/li>\n\n\n\n<li>Loop-In \/ Loop-Out als vertikale Linien (wie im Hauptplayer-Slider)<\/li>\n\n\n\n<li>7 gleichbreite Sektionsstreifen (Singing-Call-Farben O\/1\/2\/M\/3\/4\/C) am unteren Rand<\/li>\n\n\n\n<li>Das Widget ist <strong>skin-bewusst<\/strong> \u2014 Farben wechseln bei Skin-Wechsel automatisch.<\/li>\n\n\n\n<li>Ein-\/ausschaltbar per INI: <code>display\/statusbar_player = true<\/code> (Standard) \/ <code>false<\/code><\/li>\n\n\n\n<li>Kein Performance-Overhead: Update nur wenn sich Werte tats\u00e4chlich \u00e4ndern (<code>update_state<\/code> mit Dirty-Check).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Refactoring: Entwicklungsrichtlinie dokumentiert<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue <strong>Refactoring-Vollst\u00e4ndigkeitsregel<\/strong> in <code>1_Source\/docs\/12_erfahrungen.md<\/code>:<\/li>\n\n\n\n<li>Zweiphasen-Vorgehen: erst Aufbau (neues erstellen), dann nach Test Abbau (Altes entfernen)<\/li>\n\n\n\n<li>Pflicht-Checkliste: Aufbau-Liste + Abbau-Liste vor dem Coden<\/li>\n\n\n\n<li><code>CLAUDE.md<\/code> verweist jetzt mit Tabelle auf alle Subdokumente (wann welches lesen)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.84 \u2014 Evening Planner Transfer-Dialog + Audio-Device-Selector + Crash-Fix (2026-05-22)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Evening Planner \u2014 Transfer-Dialog mit Best\u00e4tigung (BL-124)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u201eZur Playliste&#8220; und \u201eZu Notizen&#8220;<\/strong> zeigen jetzt immer einen Best\u00e4tigungs-Dialog \u2014 auch wenn keine Songs best\u00e4tigt sind.<\/li>\n\n\n\n<li>Der Dialog informiert \u00fcber die Anzahl best\u00e4tigter und unbest\u00e4tigter Songs und bietet drei Optionen: <strong>Alle \u00fcbertragen \/ Nur best\u00e4tigte \/ Abbrechen<\/strong>.<\/li>\n\n\n\n<li>Sind alle Songs bereits best\u00e4tigt, entf\u00e4llt die Auswahlm\u00f6glichkeit und der Transfer l\u00e4uft direkt durch.<\/li>\n\n\n\n<li>Nach dem Transfer erscheint eine R\u00fcckmeldung mit der Anzahl \u00fcbertragener Songs.<\/li>\n\n\n\n<li><strong>Bugfix:<\/strong> Wenn nichts best\u00e4tigt war, passierte beim Klick auf die Transfer-Buttons schlicht nichts \u2014 kein Dialog, keine Meldung. Behoben.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Evening Planner \u2014 falsche Reihenfolge beim Notizen-Export<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Songs erschienen nach dem Export in die Notizen in umgekehrter Reihenfolge.<\/li>\n\n\n\n<li>Ursache: das Notes-Widget f\u00fcgt neue Eintr\u00e4ge immer oben ein (<code>index=0<\/code>), wodurch beim sequenziellen Einf\u00fcgen der letzte Song oben landete.<\/li>\n\n\n\n<li>Fix: Die Export-Liste wird vor dem Einf\u00fcgen umgekehrt, sodass die Reihenfolge aus dem Evening Planner erhalten bleibt.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: P\/S-Markierung in Notizen-Shortcodes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim Export in die Notizen werden Songs jetzt als <strong>P<\/strong> (Patter) oder <strong>S<\/strong> (Singing Call) markiert: <code>[load_song title=\"...\" mode=\"P\"]<\/code>.<\/li>\n\n\n\n<li>Verhindert Verwechslungen bei Songs, die f\u00fcr beide Typen registriert sind.<\/li>\n\n\n\n<li>R\u00fcckw\u00e4rtskompatibel: Songs ohne Typ-Zuordnung verwenden weiterhin das alte Format <code>[load_song \"...\"]<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Audio-Ausgabeger\u00e4t w\u00e4hlen (BL-126)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neue ComboBox<\/strong> dauerhaft in der rechten Statusleiste zum W\u00e4hlen des Audio-Ausgabeger\u00e4ts.<\/li>\n\n\n\n<li>Zeigt alle verf\u00fcgbaren Ausgabeger\u00e4te des Systems (gefiltert auf Ausgabe-f\u00e4hige Ger\u00e4te).<\/li>\n\n\n\n<li>Erster Eintrag: <strong>System-Standard<\/strong> (bisheriges Verhalten).<\/li>\n\n\n\n<li>Ger\u00e4tewechsel funktioniert auch w\u00e4hrend laufender Wiedergabe \u2014 der Stream wird sofort auf das neue Ger\u00e4t umgeschaltet.<\/li>\n\n\n\n<li>Auswahl wird in der INI gespeichert und beim n\u00e4chsten Start automatisch wiederhergestellt.<\/li>\n\n\n\n<li>Fallback: Ist das gespeicherte Ger\u00e4t nicht verf\u00fcgbar (z. B. USB-Soundkarte nicht angeschlossen), startet die App automatisch mit dem System-Standard.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Crash nach Audio-Device-Disconnect (TIC-0026)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Crash \u201eCannot operate on a closed database&#8220;<\/strong> trat auf wenn ein Audio-Ger\u00e4t getrennt wurde: Der Feeder stoppte die Wiedergabe, ein bereits eingereihter Timer-Callback versuchte danach noch auf die bereits geschlossene Datenbank zuzugreifen.<\/li>\n\n\n\n<li>Fix: <code>timer.stop()<\/code> wird jetzt als allererste Aktion in <code>closeEvent<\/code> ausgef\u00fchrt. Zus\u00e4tzliche <code>is_open()<\/code>-Guards in <code>_do_auto_advance<\/code> und <code>_get_current_target_duration<\/code> verhindern Zugriffe auf eine geschlossene DB.<\/li>\n\n\n\n<li><strong>Audio-Recovery:<\/strong> Wird ein Ger\u00e4t w\u00e4hrend der Wiedergabe getrennt (USB, HDMI), l\u00e4uft die Wiedergabe nach einem kurzen Ausfall automatisch auf dem n\u00e4chsten verf\u00fcgbaren Ger\u00e4t (i. d. R. interner Lautsprecher) weiter. Der Stream wird alle 2 Sekunden auf Aktivit\u00e4t gepr\u00fcft und bei Bedarf neu gestartet.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.83 \u2014 Feedback-Notizen + Lokations-Tipps + KI-Metadaten f\u00fcr Quality\/ERR (2026-05-21)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Notizfeld im Feedback-Dialog<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neues Textfeld \u201eNotizen f\u00fcr die Zukunft&#8220;<\/strong> im Feedback-Dialog (nach den Quality- und ERR-Buttons), 3-zeilig.<\/li>\n\n\n\n<li>Wenn eine Lokation gew\u00e4hlt ist: Eintrag wird beim OK direkt als neue Notiz <strong>ans Ende der Notizliste<\/strong> der aktuellen Lokation angef\u00fcgt \u2014 ideal als Ged\u00e4chtnisst\u00fctze f\u00fcr den n\u00e4chsten Abend.<\/li>\n\n\n\n<li>Wenn keine Lokation gew\u00e4hlt: Feld deaktiviert mit erkl\u00e4rendem Hinweistext im Platzhalter (\u201eZuerst eine Lokation w\u00e4hlen&#8220;).<\/li>\n\n\n\n<li>Speicherung direkt in die DB (robust gegen lazy-init des Notes-Docks) + anschlie\u00dfender Refresh des NotesWidget.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Geplante Anzahl Tips pro Lokation<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neues Einstellungsfeld<\/strong> im Lokations-Settings-Dialog (unter dem Tempo-Spinner): Anzahl der geplanten Tips pro Abend.<\/li>\n\n\n\n<li>SpinBox 0\u201340, 0 = keine Vorgabe (wird als \u201e\u2013 (keine Vorgabe)&#8220; angezeigt).<\/li>\n\n\n\n<li>Beim Lokationswechsel wird der Wert automatisch an zwei Stellen \u00fcbernommen:<\/li>\n\n\n\n<li><strong>Autofill-Dialog<\/strong> (Zauberstab im Planner): <code>spin_tipps<\/code> startet mit dem Lokations-Wert statt fest verdrahtetem Standardwert 8.<\/li>\n\n\n\n<li><strong>Evening Planner<\/strong>: <code>_spin_tips<\/code> wird auf den Lokations-Wert gesetzt.<\/li>\n\n\n\n<li>DB-Migration: neue Spalte <code>planned_tips INTEGER<\/code> in der <code>locations<\/code>-Tabelle.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: KI-Metadaten-Export f\u00fcr Quality und ERR (Potential-Widget)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Quality und ERR<\/strong> sind jetzt w\u00e4hlbare Felder im \u201eL\u00fccken exportieren&#8220;-Dialog.<\/li>\n\n\n\n<li>\u201eFehlend&#8220; bedeutet: <code>quality = 0<\/code> bzw. <code>err = 0<\/code>.<\/li>\n\n\n\n<li><strong>KI-Prompt<\/strong> erkl\u00e4rt Quality und ERR mit vollst\u00e4ndigen Anweisungen:<\/li>\n\n\n\n<li>Quality: Caller-Eigeneinsch\u00e4tzung (KI kann das nicht beurteilen) \u2192 KI setzt immer 6, Caller korrigiert selbst.<\/li>\n\n\n\n<li>ERR: T\u00e4nzer-Reaktion (1 = H\u00f6hepunkt bis 4 = Beruhigung) \u2192 KI sch\u00e4tzt anhand Bekanntheit, Mitgr\u00f6lfaktor, emotionaler Wirkung. Feld ist Pflicht, nie auslassen.<\/li>\n\n\n\n<li><strong>Import<\/strong> verarbeitet quality und ERR als Integer-Felder (<code>update_song_simple_field<\/code>). Wert 0 wird beim Import \u00fcbersprungen.<\/li>\n\n\n\n<li><strong>Buttons im FlowWidget<\/strong>: alle Buttons liegen jetzt nebeneinander und umbrechen automatisch in die n\u00e4chste Zeile wenn der Platz nicht reicht \u2014 wiederverwendbare <code>_FlowWidget<\/code>-Klasse f\u00fcr die gesamte App.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.82 \u2014 Feedback-Dialog + Musik- und Lyric-Varianten + Pattern\u2192Patter (2026-05-20)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Song-Feedback nach dem Abspielen (BL-119 + BL-035)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer modaler Feedback-Dialog<\/strong> erscheint nach jedem Songende (nat\u00fcrliches Ende, Fadeout, manueller Stop), wenn <code>feedback\/enabled = true<\/code> in der INI gesetzt ist (Standard: aus).<\/li>\n\n\n\n<li><strong>Quality-Buttons 0\u201310<\/strong> mit Farbgradient von Wei\u00df (0 = nicht bewertet) \u00fcber Hellgr\u00fcn bis Waldgr\u00fcn (10 = exzellent). Aktuell eingestellter Wert ist hervorgehoben.<\/li>\n\n\n\n<li><strong>ERR-Buttons 0\/4\/3\/2\/1<\/strong> in der Reihenfolge schw\u00e4chste \u2192 st\u00e4rkste T\u00e4nzer-Reaktion, eingef\u00e4rbt mit den Evening-Planner-Farben (Grau\/Blau\/Gr\u00fcn\/Amber\/Rot). Tooltips erkl\u00e4ren die Bedeutung beim Hover.<\/li>\n\n\n\n<li><strong>Adaptive Textfarbe:<\/strong> Dunkler Text auf hellen Buttons, wei\u00dfer Text auf dunklen \u2014 automatisch via Leuchtdichte-Formel.<\/li>\n\n\n\n<li>Esc oder \u201eAbbrechen&#8220; schlie\u00dft ohne Speichern. Nur ge\u00e4nderte Felder werden in die DB geschrieben.<\/li>\n\n\n\n<li><strong>Auto-Advance wartet<\/strong> automatisch bis der Dialog geschlossen ist (modaler Dialog blockiert den Main-Thread).<\/li>\n\n\n\n<li><strong>Manueller Aufruf<\/strong> jederzeit \u00fcber den neuen \u201eFeedback&#8220;-Button im Song-Daten-Dock (neben \u201eErweiterte Daten&#8220; und \u201eSong l\u00f6schen&#8220;).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature: Mehrere Musik- und Lyric-Dateien pro Song (BL-XXX)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Varianten-Verwaltung<\/strong> im Dialog \u201eErweiterte Song-Daten&#8220; (neuer Tab \u201eVarianten&#8220;).<\/li>\n\n\n\n<li>\u00dcber <strong>+ Musik-Variante<\/strong> bzw. <strong>+ Lyric-Variante<\/strong> k\u00f6nnen beliebig viele Alternativdateien pro Song eingetragen werden \u2014 mit sprechendem Namen (z.B. \u201eLive-Version&#8220;) und Dateiauswahl-Dialog.<\/li>\n\n\n\n<li>Varianten werden in der <code>song_properties<\/code>-Tabelle gespeichert (<code>music_2_name<\/code>, <code>music_2_file<\/code>, etc.), keine Schema-\u00c4nderung n\u00f6tig.<\/li>\n\n\n\n<li>L\u00f6schen einer Variante mit \u2715-Button; verbleibende Varianten werden automatisch neu nummeriert.<\/li>\n\n\n\n<li>Sind Varianten vorhanden, erscheinen im <strong>Song-Daten-Dock<\/strong> direkt unterhalb des Dateinamens bzw. der Lyrics-Zeile <strong>Auswahl-Buttons<\/strong>: \u201eDefault&#8220; \/ \u201eStandard&#8220; ist immer die erste und vorausgew\u00e4hlte Option.<\/li>\n\n\n\n<li>Klick auf eine Musik-Variante l\u00e4dt sie sofort im Player (PathManager sucht wie bei Hauptdateien in allen konfigurierten Music-Slots).<\/li>\n\n\n\n<li>Klick auf eine Lyric-Variante zeigt sie sofort im Lyrics-Widget.<\/li>\n\n\n\n<li>Die aktive Lyric-Variante bleibt beim Bearbeiten von Songfeldern (Autosave) und Skin-Wechsel erhalten. Beim Wechsel auf einen anderen Song wird immer auf \u201eStandard&#8220; zur\u00fcckgesetzt.<\/li>\n\n\n\n<li>Datei-Dialoge starten standardm\u00e4\u00dfig im jeweiligen Music- bzw. Lyrics-Ordner; portabler Dateiname wird relativ gespeichert.<\/li>\n\n\n\n<li><strong>Bugfix:<\/strong> Varianten-Buttons sprangen nach jeder Player-R\u00fcckmeldung auf \u201eStandard&#8220; zur\u00fcck. Aktive Variante wird jetzt im Widget gemerkt und beim Button-Rebuild korrekt wiederhergestellt.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Umbenennung: \u201ePattern&#8220; \u2192 \u201ePatter&#8220;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auf Empfehlung eines amerikanischen Callers: Die gesamte UI verwendet jetzt den korrekten Begriff \u201ePatter&#8220; statt \u201ePattern&#8220; \u2014 in allen deutschen und englischen Texten (Checkbox, RadioButton, Import-Dialog, Evening-Planner, Statistik, Spalten\u00fcberschriften, Tooltips, Tutorial-Texte).<\/li>\n\n\n\n<li>Interne Code-Variablen und DB-Felder (<code>is_pattern<\/code> etc.) bleiben unver\u00e4ndert.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.81 \u2014 Bugfix: Slider-Anzeige bei Tempo-\u00c4nderung und Loop-Audition (2026-05-18)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Zeitanzeige inkonsistent bei ver\u00e4ndertem Tempo<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>label_time_current<\/code> zeigte Original-Sekunden<\/strong>, <code>label_time_total<\/code> hingegen Echtzeit-Dauer \u2014 unterschiedliche Einheiten. Beispiel bei 3-Min-Song, Tempo 1,5\u00d7, nach 1 Minute: Labels zeigten \u201e1:30 \/ 2:00&#8243; (impliziert 75 %), Slider stand korrekt bei 50 %. Jetzt zeigt auch die laufende Zeit Echtzeit: <code>pos \u00d7 dur \/ orig_dur<\/code>. Labels und Slider stimmen wieder \u00fcberein.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Slider friert bei Loop-Audition ein<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Slider blieb w\u00e4hrend der 5-Sekunden-Vorh\u00f6rphase<\/strong> (vor dem ersten Loop-Sprung) auf der <code>loop_in<\/code>-Position stehen. Ursache: <code>_estimate_playback_pos()<\/code> klemmte die Position auf <code>max(loop_in, ...)<\/code>, sobald der Feed-Pointer nach dem Feed-Ahead-Wrap bereits hinter <code>loop_in<\/code> lag \u2014 obwohl der Audio-Callback noch im Pre-Loop-Segment spielte. Fix: Bei <code>pos &lt; loop_in<\/code> wird jetzt <code>_playback_sample<\/code> als N\u00e4herung verwendet (exakt bei Tempo 1,0; leichte Abweichung bei anderen Tempos).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.80 \u2014 Audio-Architektur: Dedizierter Feeder-Thread (2026-05-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Audio-Aussetzer endg\u00fcltig behoben (TIC-0025)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Dedizierter Audio-Feeder-Thread<\/strong> in der <code>AudioEngine<\/code>. Bisher wurde der WSOLA-Stretcher vom UI-Main-Thread aus gef\u00fcllt (alle 50 ms via QTimer aus <code>PlayerWidget.update_display<\/code>). Damit war das Audio-Feeding vollst\u00e4ndig vom UI-Thread abh\u00e4ngig: jede GIL-Blockade &gt; 500 ms (Loop-Finder-Completion, DB-Operationen, restoreState) f\u00fchrte zu h\u00f6rbaren Aussetzern. <strong>Jetzt l\u00e4uft ein eigener Daemon-Thread (<code>AudioFeeder<\/code>)<\/strong>, der den Stretcher unabh\u00e4ngig vom Main-Thread alle 20 ms nachf\u00fcllt.<\/li>\n\n\n\n<li><strong><code>FEED_AHEAD_SECONDS<\/code>: 0.5 s \u2192 5.0 s.<\/strong> Der Stretcher puffert ab sofort 5 Sekunden Audio vor. Selbst wenn der Main-Thread mehrere Sekunden blockiert, hat der Audio-Callback genug Daten zum Abspielen.<\/li>\n\n\n\n<li><strong>Thread-sichere Zustands-Updates<\/strong> via <code>threading.Lock<\/code>: <code>load()<\/code>, <code>seek()<\/code>, <code>play()<\/code> und <code>_flush_and_refeed()<\/code> halten den Lock, w\u00e4hrend sie <code>_feed_pos<\/code>, <code>audio_data<\/code> oder den <code>stretcher<\/code> \u00e4ndern. Keine Race-Conditions zwischen Feeder-Thread und Main-Thread m\u00f6glich.<\/li>\n\n\n\n<li><strong>Ergebnis:<\/strong> Ein aktiver AudioStream hat ab jetzt absolute Priorit\u00e4t \u2014 er wird nicht mehr von UI-Operationen ausgehungert.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Weitere Rule-Aktionen entkoppelt<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>dual_view_toggle<\/code> deferred<\/strong> via <code>QTimer.singleShot(0, ...)<\/code> \u2014 gleiches Muster wie <code>layout_load<\/code> in v0.79. Die Toggle-Pfade mit <code>restoreState<\/code>\/<code>restoreGeometry<\/code> blockierten bis zu 105 ms.<\/li>\n\n\n\n<li><strong><code>system_ping<\/code> asynchron<\/strong> im Daemon-Thread \u2014 <code>winsound.Beep<\/code> blockierte den Main-Thread synchron f\u00fcr die volle Tondauer (~300 ms). Trigger ist jetzt sofort durch, der Beep spielt parallel.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.79 \u2014 Performance: layout_load deferred (2026-05-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Audio-Aussetzer bei Layout-Wechsel durch Rules (TIC-0025)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>layout_load<\/code>-Aktion deferred<\/strong> \u2014 <code>restoreState<\/code>\/<code>restoreGeometry<\/code> blockierten ~75 ms synchron auf dem Main-Thread (GIL), genau beim <code>song_started<\/code>-Trigger. Mit <code>QTimer.singleShot(0, ...)<\/code> wird der Layout-Wechsel in den n\u00e4chsten Event-Loop-Tick verschoben, sodass der Audio-Callback zuerst l\u00e4uft. Identisches Muster wie die bereits deferred <code>play<\/code>-Aktion.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.78 \u2014 Performance: Audio-Aussetzer (2026-05-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Song-Aussetzer im Livebetrieb (TIC-0025)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Songliste: <code>set_last_played_map<\/code> optimiert<\/strong> \u2014 bisher wurden beim Song-Start alle 2401 Tabellenzeilen neu geschrieben (144 ms GIL-Block auf dem UI-Thread). Jetzt werden nur noch die tats\u00e4chlich ge\u00e4nderten Zeilen aktualisiert (typisch: 1 Zeile, ~0 ms). Behebt die Hauptursache f\u00fcr Audio-Aussetzer auf schw\u00e4cheren Rechnern.<\/li>\n\n\n\n<li><strong><code>_apply_filter<\/code> baut <code>_row_by_id<\/code>-Dict<\/strong> auf (song_id \u2192 Zeilenindex) f\u00fcr direkten Zugriff ohne lineare Suche.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rule Engine: Aktions-Timing im Log<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Jede Rule-Aktion protokolliert jetzt ihre Ausf\u00fchrungszeit in <code>rules\/rules.log<\/code> (z.B. <code>song_list_refresh({}) [2.1ms]<\/code>). Erleichtert die Diagnose von Performance-Problemen im Livebetrieb.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.77 \u2014 Permanent Custom-Filter (2026-05-14)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Planner \u2014 Permanente Custom-Filter-Slots<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u201ePermanent&#8220;-Toggle-Button<\/strong> in jeder der 4 Custom-Filter-Slot-Zeilen (hinter dem Entfernen-Button)<\/li>\n\n\n\n<li>Ist der Button gedr\u00fcckt, wird der Dateipfad der geladenen Playlist in der INI (Sektion <code>custom-filter<\/code>) gespeichert<\/li>\n\n\n\n<li>Beim Entfernen eines Slots wird der Permanent-Status automatisch zur\u00fcckgesetzt<\/li>\n\n\n\n<li>Beim ersten \u00d6ffnen des Planners in einer Session werden permanente Eintr\u00e4ge aus der INI gelesen und die Playlisten automatisch als Custom-Filter geladen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.76 \u2014 Planner Custom-Filter (BL-097) (2026-05-12)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Planner \u2014 Custom-Playlist-Filter<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u201eCustom&#8220;-Button<\/strong> in der Filter-Zeile (nach Alle\/Pattern\/Singing, vor Genre): \u00f6ffnet den neuen Custom-Filter-Dialog<\/li>\n\n\n\n<li><strong>Custom-Filter-Dialog<\/strong>: bis zu 4 feste Slots, je mit [Laden]- und [Entfernen]-Button; l\u00e4dt gespeicherte Playlist-TXT-Dateien (aktuelles und altes Format)<\/li>\n\n\n\n<li><strong>Vorschau-Tabelle<\/strong> im Dialog zeigt die Schnittmenge aller geladenen Slots in Echtzeit<\/li>\n\n\n\n<li><strong>Anzeigename<\/strong> per Doppelklick auf den Slot-Namen \u00e4nderbar (Playlist-Daten bleiben unver\u00e4ndert)<\/li>\n\n\n\n<li><strong>Extra-Zeile im Planner<\/strong> erscheint nach dem \u00dcbernehmen mit Checkboxen pro geladenem Slot \u2014 nur sichtbar wenn mindestens eine Playlist geladen ist<\/li>\n\n\n\n<li>Checkboxen an\/aus filtert den Song-Pool sofort auf die Schnittmenge der aktiven Playlisten<\/li>\n\n\n\n<li>Alle anderen Filter (Suche, Sortierung, Typ, Genre) bleiben weiterhin wirksam<\/li>\n\n\n\n<li>Filter ist session-only (kein Persist beim App-Ende)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.75 \u2014 Quality + ERR F\u00fcllen, Evening Planner Fixes (2026-05-11)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Tab im Potential-Widget: Quality + ERR F\u00fcllen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Einzel-Datensatz-Durchlauf<\/strong>: Songs mit fehlender Quality oder ERR-Bewertung werden einzeln angezeigt \u2014 kein Listenspringen mehr<\/li>\n\n\n\n<li>Doppelklick auf Loops-Spalte oeffnet Loop-Anzahl-Dialog (Playlist + Planner)\/strong&gt;: Titel (fett), darunter Typ (Pattern \/ Singing \/ Pattern + Singing), Label, aktueller Quality- und ERR-Wert<\/li>\n\n\n\n<li><strong>Quality-Buttons<\/strong> (1\u201310): nur sichtbar wenn Quality nicht gesetzt; aktueller Wert hervorgehoben<\/li>\n\n\n\n<li><strong>ERR-Buttons<\/strong> (1\u20134): in ERR-Farben (Rot \/ Orange \/ Gr\u00fcn \/ Blau); nur sichtbar wenn ERR nicht gesetzt<\/li>\n\n\n\n<li><strong>Auto-Advance<\/strong>: Sobald beide Werte gesetzt sind, springt die Anzeige automatisch zum n\u00e4chsten Song<\/li>\n\n\n\n<li><strong>\u201e\u25b6 Vorh\u00f6ren&#8220; \/ \u201e\u23f9 Stopp&#8220;<\/strong> Button neben dem Titel: l\u00e4dt den Song in den Player und startet die Wiedergabe; zweiter Klick stoppt<\/li>\n\n\n\n<li>Navigation mit \u201e\u25c0 Zur\u00fcck&#8220; \/ \u201eWeiter \u25b6&#8220; (gut lesbar) + Z\u00e4hler \u201eSong X von Y&#8220;<\/li>\n\n\n\n<li>Badge-Count im Tab-Titel<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Evening Planner Fixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ERR-Balken erschienen nie<\/strong>: Songs mit <code>err=0<\/code> (nicht bewertet) lieferten <code>patter_err=0<\/code> \u2192 <code>_draw_bar<\/code> zeichnete nichts. Fix: Songs mit <code>err=0<\/code> aber vorhandenem Slot bekommen einen <strong>grauen Balken<\/strong> auf Ziel-ERR-H\u00f6he (konsistent mit Tabellen-Verhalten)<\/li>\n\n\n\n<li><strong>Dock nicht dockbar<\/strong>: Evening Planner Dock ist jetzt nur noch schlie\u00dfbar (kein Movable\/Floatable) \u2014 bleibt auch nach <code>restoreState()<\/code> fest<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Weitere Fixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>KI-Prompt<\/strong> im Metadaten-Tab ist jetzt immer auf Englisch<\/li>\n\n\n\n<li><strong>Statistik-Texte<\/strong> nach Export\/Import\/CSV-Abgleich vollst\u00e4ndig \u00fcbersetzt (keine hardcodierten deutschen Strings mehr)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.74 \u2014 Metadaten-Werkzeuge: Song-Properties, CSV-Abgleich, Metadaten-Export\/Import (2026-05-11)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Funktion: Erweiterte Song-Daten (BL-094)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Generische <code>song_properties<\/code>-Tabelle<\/strong>: Speichert beliebige Schl\u00fcssel-Wert-Paare pro Song (initial: <code>original_artist<\/code>, <code>release_year<\/code>)<\/li>\n\n\n\n<li><strong>Button \u201eErweiterte Daten&#8220;<\/strong> im Song-Datensatz \u00f6ffnet einen generischen Editor mit bearbeitbarer Key-Value-Tabelle<\/li>\n\n\n\n<li><strong>Label-Feld<\/strong> umbenannt zu \u201eLabel + Nr.&#8220; mit Beispiel-Platzhalter \u201ez.B. SQR 123&#8243;<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Widget-Layout im Potential-Widget<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Umbau zu QTabWidget<\/strong>: Jede der 10 Pr\u00fcfungen bekommt einen eigenen Tab (Badge-Count im Tab-Titel)<\/li>\n\n\n\n<li>Erster Tab wird beim \u00d6ffnen automatisch geladen<\/li>\n\n\n\n<li>Tab-Scroll-Buttons verbreitert (24 px Mindestbreite)<\/li>\n\n\n\n<li><strong>Neuer Tab \u201eMetadaten f\u00fcllen&#8220;<\/strong> (BL-114) mit drei Werkzeugen:<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Metadaten-Werkzeuge (BL-114)<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Abgleichen mit Music CSV<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CSV-Abgleich-Button<\/strong> (an erster Stelle): Gleicht fehlende Song-Metadaten automatisch mit einer mitgelieferten CSV-Datenbank ab<\/li>\n\n\n\n<li>Dreistufiges Matching: 1) exakter Titel, 2) Label-Code + Nummer, 3) Fuzzy (difflib, Schwelle 0.80)<\/li>\n\n\n\n<li><strong>Preview-Tabelle<\/strong> mit Checkbox pro Song, \u201eAlle \/ Keine&#8220; Auswahl<\/li>\n\n\n\n<li>Gr\u00fcne Zellen = eindeutiger Treffer, gelbe Zellen = mehrdeutig \u2192 Doppelklick \u00f6ffnet Auswahllist<\/li>\n\n\n\n<li>Unterst\u00fctzte Felder: Interpret, Label\/Nr., Genre, Original Artist, Erscheinungsjahr<\/li>\n\n\n\n<li><code>music-extended-data\/music_extended_data.csv<\/code> wird bei jedem Release automatisch mitgeliefert<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">L\u00fccken exportieren (JSON)<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Feld-Auswahl-Dialog (welche leeren Felder exportieren?)<\/li>\n\n\n\n<li>Exportiert Songs mit fehlenden Daten als JSON mit <code>genres_available<\/code>-Liste<\/li>\n\n\n\n<li>Statistik nach Export (Anzahl Songs, fehlende Felder)<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">KI-Prompt anzeigen<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kopierfertige Anleitung f\u00fcr KI-Assistenten, <strong>immer auf Englisch<\/strong><\/li>\n\n\n\n<li>Enth\u00e4lt alle im System vorhandenen Genres als erlaubte Werte<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Daten importieren (JSON)<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L\u00e4dt angereicherte JSON zur\u00fcck, zeigt Preview-Tabelle mit Checkbox-Auswahl<\/li>\n\n\n\n<li>Unbekannte Genres werden markiert und \u00fcbersprungen<\/li>\n\n\n\n<li>Alle Statistik-Texte vollst\u00e4ndig \u00fcbersetzt (keine hardcodierten deutschen Strings mehr)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Playlist-Kompatibilit\u00e4t<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>V1-Playlisten<\/strong> (nur Titel, altes Format) werden wieder korrekt geladen<\/li>\n\n\n\n<li>Neue Playlisten werden mit Titel statt Dateiname gespeichert (Format V3: Typ + Loop-Count + Titel)<\/li>\n\n\n\n<li>Loader erkennt alle drei Formate automatisch (V1\/V2\/V3)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.73 \u2014 Abendplanung: Evening Planner Widget (2026-05-10)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Potential-Widget: Neue Pr\u00fcfer<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ohne ERR<\/strong> (BL-115): Listet Songs auf, bei denen der ERR-Wert noch nicht gesetzt ist (<code>err = 0<\/code>). Doppelklick navigiert direkt zum Song.<\/li>\n\n\n\n<li><strong>Ohne Genre<\/strong> (BL-116): Listet Songs ohne Genre-Zuweisung auf. Doppelklick navigiert direkt zum Song.<\/li>\n\n\n\n<li><strong>Inkompatibles Format<\/strong> (BL-117): Pr\u00fcft ob Audiodateien vom internen Decoder (soundfile\/libsndfile) gelesen werden k\u00f6nnen. Erkennt MP3s mit nicht-standardkonformen Frames, die nur ffmpeg-basierte Player lesen k\u00f6nnen. L\u00e4uft wie BPM- und Loop-Check mit Zeitsch\u00e4tzung (5 Sample-Dateien \u2192 Hochrechnung \u2192 Best\u00e4tigung \u2192 vollst\u00e4ndiger Check im Hintergrundthread). Doppelklick navigiert zum betroffenen Song; Ignorieren-Funktion vorhanden.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Import neuer Songs schl\u00e4gt fehl<\/strong> (<code>You did not supply a value for binding parameter :err<\/code>): <code>err<\/code> fehlte im <code>insert()<\/code>-Dict \u2014 die Spalte war beim Hinzuf\u00fcgen von BL-111 im SQL erg\u00e4nzt worden, aber nicht im Python-Dict. Neue Songs werden immer mit <code>err = 0<\/code> (nicht gesetzt) importiert. <code>insert()<\/code> und <code>update()<\/code> verwenden jetzt <code>dataclasses.asdict()<\/code> statt manueller Dicts \u2014 neue Felder im Song-Modell werden k\u00fcnftig automatisch ber\u00fccksichtigt.<\/li>\n\n\n\n<li><strong>Crash beim Songimport behoben<\/strong> (<code>TypeError: '&gt;' not supported between instances of 'str' and 'int'<\/code>): <code>quality<\/code>-Werte die als Text oder Kommazahl in der DB lagen (z.B. aus \u00e4lteren Migrationen) konnten die App beim Start komplett blockieren. <code>_row_to_song<\/code> konvertiert <code>quality<\/code> jetzt robust zu <code>int<\/code>; eine automatische DB-Migration bereinigt bestehende Altdaten beim ersten Start der neuen Version.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Feature: Evening Planner (Abendplanung)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer Dock \u201eAbendplanung&#8220;<\/strong> parallel zum bestehenden Planner (Ansicht-Men\u00fc)<\/li>\n\n\n\n<li><strong>Emotionaler Spannungsbogen<\/strong>: Bezier-Kurve mit Catmull-Rom-Interpolation als visuelles Ziel<\/li>\n\n\n\n<li><strong>S\u00e4gezahn-Bl\u00f6cke<\/strong>: CurveEngine segmentiert N Tipps automatisch in Bl\u00f6cke (konfigurierbares Min\/Max, Standard 3\u20135 Tipps), jeder Block mit ERR-Muster 3\u21924\u21922\u21921<\/li>\n\n\n\n<li><strong>ERR-Balken<\/strong>: Patter (satte Farbe) und Singer (<a href=\"https:\/\/callerscaddy.de\/farbwechsel-via-theme\/\">helle Farbe<\/a>) als separate Balken pro Tipp; H\u00f6he = emotionale Intensit\u00e4t<\/li>\n\n\n\n<li><strong>Drag-Handles<\/strong>: ERR-Ziele per Maus verschieben; Griff-Abstand konfigurierbar (pro Tipp \/ 30 \/ 45 \/ 60 \/ 90 min)<\/li>\n\n\n\n<li><strong>Pausen-Unterst\u00fctzung<\/strong>: Pausen als graue Bl\u00f6cke im Zeitstrahl, proportional zur Dauer dargestellt; harte Block-Grenzen<\/li>\n\n\n\n<li><strong>Songvorschl\u00e4ge<\/strong>: SongScorer bewertet nach <code>quality \u00d7 days_since_last_played \u00d7 err_match<\/code>; bester Vorschlag automatisch grau vorbelegt<\/li>\n\n\n\n<li><strong>Ausgleichsregel<\/strong>: Singer-ERR komplement\u00e4r zu Patter-ERR (Summe \u2248 5)<\/li>\n\n\n\n<li><strong>4 Strategien<\/strong>: Pattern+Singing abwechselnd, Singings nur Anfang\/Ende, Nur Pattern, Nur Singings<\/li>\n\n\n\n<li><strong>Detail-Liste (PlannerTable)<\/strong>: Tabellarische Ansicht aller Tipps mit Zeit, Songtitel, Label, ERR; Pausen per Drag &amp; Drop verschiebbar<\/li>\n\n\n\n<li><strong>Zoom &amp; Pan<\/strong>: Zoom-in\/out\/fit-Buttons, QScrollArea f\u00fcr horizontales Panning<\/li>\n\n\n\n<li><strong>Lokation-Integration<\/strong>: Automatische Aktualisierung der Vorschl\u00e4ge bei Lokationswechsel<\/li>\n\n\n\n<li><code>song_db.py<\/code>: Neue Methode <code>get_planner_candidates()<\/code> f\u00fcr ERR-gefiltertes Kandidaten-Query<\/li>\n\n\n\n<li><strong>Kandidaten-Dialog<\/strong>: Doppelklick auf einen Tipp-Slot \u00f6ffnet einen Dialog mit allen passenden Kandidaten (Score, ERR, Label, Dateiname); beim Pattern-Slot optionale Bonus-Spalten f\u00fcr Genre-Match und Label-Match; Doppelklick oder OK best\u00e4tigt den Song f\u00fcr diesen Slot<\/li>\n\n\n\n<li><strong>Genre-Filter<\/strong>: Checkbox + Button schr\u00e4nkt Song-Kandidaten auf ausgew\u00e4hlte Genres ein (gilt f\u00fcr Auto-Fill und Kandidaten-Dialog); Button zeigt kompakte Zusammenfassung der gew\u00e4hlten Genres<\/li>\n\n\n\n<li><strong>Planungsregeln-Dialog<\/strong>: Konfigurierbare Regeln f\u00fcr die Vorschlagsberechnung<\/li>\n\n\n\n<li><strong>Balance<\/strong>: Patter-ERR komplement\u00e4r zu Singing-ERR (Summe \u2248 5)<\/li>\n\n\n\n<li><strong>Same-Genre-Boost<\/strong> \/ <strong>Same-Label-Boost<\/strong>: multiplikativer Score-Bonus (Faktor konfigurierbar) wenn Patter und Singer aus gleichem Genre \/ Label<\/li>\n\n\n\n<li><strong>First-Tip-Soft<\/strong>: Erster Tipp bevorzugt Baseline\/Beruhigung<\/li>\n\n\n\n<li><strong>Last-Tip-Strong<\/strong>: Letzter Tipp bevorzugt H\u00f6hepunkt oder Vorbereitung<\/li>\n\n\n\n<li><strong>Export-Button<\/strong> (gr\u00fcner Haken): \u00dcbertr\u00e4gt alle best\u00e4tigten Slots als neue Playlist (nur best\u00e4tigte, keine grauen Vorschl\u00e4ge)<\/li>\n\n\n\n<li><strong>Zwei Fill-Algorithmen<\/strong>: <code>_fill_optimal<\/code> (globale Optimierung, minimiert Wiederholungen) und <code>_fill_greedy<\/code> (schneller, greedy je Slot)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.72 \u2014 Potential: Ohne MP3 \/ Ohne Qualit\u00e4t, Crash-Handler Qt-Erweiterung (2026-05-07)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Potential-Widget: Zwei neue Datenqualit\u00e4ts-Checks (BL-027)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ohne MP3<\/strong>: Zeigt Songs, deren MP3-Datei in keinem konfigurierten Musikordner gefunden wird<\/li>\n\n\n\n<li>Lazy Load: Dateicheck startet erst beim Klick auf den Button, nicht beim App-Start<\/li>\n\n\n\n<li>Fortschritts-Dialog w\u00e4hrend der Pr\u00fcfung (&#8222;Pr\u00fcfe MP3-Dateien\u2026 x\/n&#8220;)<\/li>\n\n\n\n<li>L\u00e4uft im Hintergrund-Thread (QThread), UI bleibt bedienbar, abbrechbar<\/li>\n\n\n\n<li>Doppelklick navigiert zum Song in der Songliste; Ignorieren-Funktion vorhanden<\/li>\n\n\n\n<li><strong>Ohne Qualit\u00e4t<\/strong>: Zeigt Songs mit <code>quality = 0<\/code> (Standardwert = noch nie bewertet)<\/li>\n\n\n\n<li>Doppelklick navigiert zum Song; Ignorieren-Funktion vorhanden<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Crash-Handler: Qt-Message-Handler (BL-103)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>qInstallMessageHandler<\/code> registriert: Qt-eigene Critical- und Fatal-Meldungen werden jetzt abgefangen<\/li>\n\n\n\n<li>Bei <code>QtCriticalMsg<\/code> und <code>QtFatalMsg<\/code>: sofortiges Schreiben eines Crash-Logfiles (inkl. Ring-Buffer)<\/li>\n\n\n\n<li>Sch\u00fctzt vor einer Klasse von Qt-internen Fehlern, die <code>sys.excepthook<\/code> nicht erreichen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.71 \u2014 ERR-Feld, Planner-Suche, Auto-Fill, Button-Wrap (2026-05-07)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">ERR-Feld: Emotional Response Rate (BL-111)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Feld <code>err<\/code> in der Songdatenbank (INTEGER, 0\u20134): bewertet die emotionale Wirkung eines Songs im Tanzabend<\/li>\n\n\n\n<li>Werte: 0 = nicht bewertet, 1 = H\u00f6hepunkt, 2 = Vorbereitung, 3 = Baseline, 4 = Beruhigung<\/li>\n\n\n\n<li>ComboBox im Song-Daten-Widget; gespeichert wird nur die Zahl, keine Texte<\/li>\n\n\n\n<li>DB-Migration: neues Feld wird bestehenden Datenbanken automatisch hinzugef\u00fcgt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Auto-Fill im Planner (BL-112)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Zauberstab-Button (3. Position in der Mittelleiste) f\u00fcllt die Playlist automatisch<\/li>\n\n\n\n<li>Dialog: Anzahl Pattern- und Singing-Tipps w\u00e4hlbar + eine von 4 Strategien:<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Zufall \u2014 Songs werden zuf\u00e4llig gezogen<\/li>\n\n\n\n<li>Selten gespielt \u2014 wenig gespielte Songs bevorzugt<\/li>\n\n\n\n<li>Qualit\u00e4t \u2014 Songs nach Qualit\u00e4tsbewertung sortiert<\/li>\n\n\n\n<li>ERR-Abfolge \u2014 Songs nach emotionaler Kurve (Vorbereitung\u2192H\u00f6hepunkt\u2192Baseline\u2192Beruhigung)<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dual-Typ-Songs (Pattern + Singing) erhalten korrekt den jeweils gew\u00e4hlten Modus<\/li>\n\n\n\n<li>Gesamtdauer der Playlist ber\u00fccksichtigt bei Loop=<a href=\"https:\/\/callerscaddy.de\/controlled-loops-patter-music\/\">\u221e die voreingestellte Pattern-Dauer des Programms<\/a>\/Clubs<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Planner-Suche (BL-106)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Suchfeld oben im Pool (linke Spalte des Planners): filtert gleichzeitig nach Titel, Label und Dateiname<\/li>\n\n\n\n<li>Mit X-Button zum Leeren; Suche wirkt zusammen mit den \u00fcbrigen Filtern (Genre, Typ usw.)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Button-Leiste mit Zeilenumbruch<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Hilfsklasse <code>_WrapButtonBar<\/code>: Buttons reihen sich nebeneinander, umbrechen aber bei zu schmalen Dock-Fenstern automatisch in eine zweite Zeile<\/li>\n\n\n\n<li>Songliste und Playlist nutzen jetzt diese Leiste \u2014 keine abgeschnittenen Beschriftungen mehr<\/li>\n\n\n\n<li>Alle Buttons einer Zeile werden auf einheitliche H\u00f6he gebracht (Zeilen-Maximum)<\/li>\n\n\n\n<li>Button-Texte kompakter: \u201e\u2192 Notiz&#8220; \u2192 \u201e+Notiz&#8220;, \u201e\u2192 Playlist&#8220; \u2192 \u201e+Playlist&#8220;<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sonstiges<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Standard-Tanzprogramm beim Start: Button zeigt \u201eMS&#8220; (Mainstream) statt \u201e\u2014&#8220;<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.70 \u2014 Potential-Widget: Bulk-Aktionen; UI-Bugfixes (2026-05-05)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Potential-Widget: Bulk-Aktionen (Erweiterung BL-027)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Auto-Loop f\u00fcr alle<\/strong>: Neuer Button im &#8222;Ohne Loop&#8220;-Check \u2014 setzt automatisch einen Loop f\u00fcr alle betroffenen Pattern per Loop-Finder. Bei mehr als 5 Songs wird vorab eine Zeitsch\u00e4tzung anhand von 5 Stichproben gemessen und dem Nutzer angezeigt, bevor er best\u00e4tigt.<\/li>\n\n\n\n<li><strong>Beat-Snap f\u00fcr alle<\/strong>: Neuer Button im &#8222;Ohne BeatSnap&#8220;-Check \u2014 snappt Loop-In und Loop-Out aller betroffenen Songs auf den n\u00e4chstgelegenen Beat. Gleiches Timing-Prinzip: bei &gt; 5 Songs Vorab-Sch\u00e4tzung, sonst direkt loslegen.<\/li>\n\n\n\n<li><strong>Leere Lokationen l\u00f6schen<\/strong>: Neuer Button im &#8222;Leere Lokationen&#8220;-Check \u2014 entfernt alle Lokationen ohne Abspielhistorie nach Best\u00e4tigung.<\/li>\n\n\n\n<li>Alle Bulk-Operationen laufen im Hintergrundthread (kein UI-Freeze), mit abbrechbarem Fortschrittsdialog (&#8222;Abbrechen&#8220;-Button).<\/li>\n\n\n\n<li>SQLite-Thread-Safety: Worker \u00f6ffnen eine eigene DB-Verbindung \u00fcber <code>db_path<\/code>, statt die Verbindung des Main-Threads zu teilen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Loop Finder Widget<\/strong>: Segmentleiste (7 Singing-Call-Abschnitte) wurde nach dem Player-Redesign unten abgeschnitten \u2014 H\u00f6he von 14 px auf 28 px korrigiert.<\/li>\n\n\n\n<li><strong>Loop-Widget Buttons<\/strong>: Unterl\u00e4ngen (p, g) in zweizeiligen Buttons (&#8222;Loop\\nFinder&#8220;, &#8222;Beat\\nSnap&#8220; etc.) wurden abgeschnitten \u2014 QPushButton-Padding in allen Themes von 10 px auf 5 px vertikal reduziert.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.69 \u2014 Rules: BPM-Bedingungen + Auto-Detect-Aktion; zentrale Pfadaufl\u00f6sung (2026-05-03)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Rules \u2014 neue Bedingungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>BPM Set<\/strong>: pr\u00fcft ob der aktuelle Song einen BPM-Wert gesetzt hat (<code>base_bpm &gt; 0<\/code>)<\/li>\n\n\n\n<li><strong>BPM Not Set<\/strong>: Gegenst\u00fcck \u2014 Song hat noch keinen BPM-Wert<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rules \u2014 neue Aktion<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Auto-Detect BPM<\/strong> (Gruppe &#8222;Audio&#8220;): Startet die automatische BPM-Erkennung f\u00fcr den aktuell geladenen Song im Hintergrund \u2014 identisch zum &#8222;Auto BPM&#8220;-Button im Song-Daten-Widget, aber als Regel-Aktion ausl\u00f6sbar (z. B. via Trigger &#8222;Song Changed&#8220; mit Bedingung &#8222;BPM Not Set&#8220;)<\/li>\n\n\n\n<li>Ergebnis wird in DB gespeichert und das BPM-Feld im Song-Daten-Widget sofort aktualisiert<\/li>\n\n\n\n<li>L\u00e4uft idempotent: zweiter Aufruf w\u00e4hrend laufender Erkennung wird ignoriert<\/li>\n\n\n\n<li>&#8222;<a href=\"https:\/\/callerscaddy.de\/die-bpm-des-square-dance-liedes-ermitteln\/\">BPM wird ermittelt \u2026<\/a>&#8222;-Overlay w\u00e4hrend der Erkennung (analog zum Auto-Loop-Overlay)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Zentrale Pfadaufl\u00f6sung (BL-104)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>PathManager.find_lyric_file(filename)<\/code> neu \u2014 sucht Lyrik-Datei im konfigurierten Lyrics-Ordner (Pendant zu <code>find_song_file()<\/code>)<\/li>\n\n\n\n<li><code>SongDataWidget._on_auto_bpm()<\/code>: nutzt jetzt <code>find_song_file()<\/code> statt direktem <code>music_dir<\/code>-Join \u2014 findet Songs in allen 4 Musik-Slots<\/li>\n\n\n\n<li><code>LyricsWidget._load_lyrics_file()<\/code>: nutzt jetzt <code>find_lyric_file()<\/code> statt direktem <code>lyrics_dir<\/code>-Join<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>TIC-0016<\/strong>: Auto-BPM-Button reagierte nicht auf Klick \u2014 Ursache war <code>music_dir<\/code>-Join der nur Slot 1 durchsuchte; behoben durch <code>find_song_file()<\/code> (Teil der zentralen Pfadaufl\u00f6sung)<\/li>\n\n\n\n<li><strong>TIC-0023<\/strong>: Funktionen ignorierten alternative Musik-\/Lyrik-Pfade (Slots 2\u20134) \u2014 behoben durch zentrale Pfadaufl\u00f6sung (BL-104)<\/li>\n\n\n\n<li><strong>TIC-0007 \/ TIC-0022<\/strong>: Abst\u00fcrze ohne Details nicht mehr analysierbar \u2014 strukturell behoben durch Crash-Handler (BL-103): automatisches Logfile bei jedem unbehandelten Absturz<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.68 \u2014 Player-Widget Redesign (2026-05-02)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Player-Widget: Neues Layout<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Info-Streifen<\/strong> (oberste Zeile): 4 gleich breite Spalten mit Beschriftung oben und Wert darunter \u2014 Dauer \/ BPM \/ Loops \/ Programm<\/li>\n\n\n\n<li><strong>BPM-Anzeige<\/strong>: zeigt nur noch den Zahlenwert, \u201eBPM&#8220; steht als Spaltentitel dar\u00fcber<\/li>\n\n\n\n<li><strong>Loop-Count<\/strong>: zeigt nur noch \u201e3\/8&#8243; bzw. \u201e\u221e&#8220;, Spaltentitel lautet \u201eLoops&#8220;<\/li>\n\n\n\n<li><strong>Songtitel + Status<\/strong> in einer gemeinsamen Zeile: Titel linksb\u00fcndig, Status rechtsb\u00fcndig<\/li>\n\n\n\n<li><strong>Songtitel dynamisch skalierend<\/strong>: nutzt allen freien vertikalen Platz der Player-Karte, Schrift w\u00e4chst von der Theme-Basisgr\u00f6\u00dfe bis +13 px \u2014 mit Zeilenumbruch bei Platzmangel<\/li>\n\n\n\n<li><strong>Status-Text<\/strong> bleibt dauerhaft in kleiner fester Schriftgr\u00f6\u00dfe (font_size \u2212 2), skaliert nicht mit dem Titel<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sektionsleiste neu<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>7 QPushButton-Segmente statt custom paintEvent<\/li>\n\n\n\n<li>Gestalt-basierte Farbgebung: O\/M\/C (strukturelle Marker) in Rot, 1\/3 in hellem Grau, 2\/4 in dunklem Grau \u2014 Muster des Singing Calls wird sofort visuell erkennbar<\/li>\n\n\n\n<li>Farben \u00fcber neue Skin-Keys <code>sec_o<\/code>, <code>sec_1<\/code>, <code>sec_2<\/code>, <code>sec_m<\/code>, <code>sec_3<\/code>, <code>sec_4<\/code>, <code>sec_c<\/code> \u2014 in allen 4 Skins hinterlegt (default, light, win11, elegant)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Transport-Buttons: SVG-Icons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Play, Pause, Stop und Fade-Out erhalten SVG-Vektorsymbole<\/li>\n\n\n\n<li>Farbe der Icons folgt dynamisch der Theme-Einstellung <code>button_text<\/code> \u2014 keine separaten SVG-Dateien pro Theme n\u00f6tig<\/li>\n\n\n\n<li>Fade-Out-Pfeil zeigt nach rechts (\u2192)<\/li>\n\n\n\n<li>Play-Button: volle Breite, Mindesth\u00f6he 44 px, Akzentfarbe aus dem Theme<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Theme-relative Schriftgr\u00f6\u00dfen im Info-Streifen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Alle Schriftgr\u00f6\u00dfen relativ zur <code>font_size<\/code>-Einstellung des Skins<\/li>\n\n\n\n<li>Beschriftungs-Labels: <code>font_size \u2212 2<\/code> px<\/li>\n\n\n\n<li>Wert-Labels (BPM, Loops): <code>font_size + 1<\/code> px<\/li>\n\n\n\n<li>Dauer-Timer: <code>font_size + 2<\/code> px, monospace fett<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Platzsparende Anpassungen (Laptop-Optimierung)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Loop-Widget<\/strong>: Button-H\u00f6hen von 52 px auf 38 px reduziert, NEU-Button von 38 auf 32 px, Spacing von 6 auf 4 px, <code>addStretch()<\/code> am unteren Rand entfernt, Bottom-Margin auf 4 px gek\u00fcrzt \u2014 spart ~100\u2013120 px Gesamth\u00f6he<\/li>\n\n\n\n<li><strong>Programm-Button<\/strong> im Info-Streifen: H\u00f6he auf max. 24 px begrenzt, internes Padding reduziert<\/li>\n\n\n\n<li><strong>Songtitel-Bereich<\/strong>: maximale H\u00f6he auf 52 px gedeckelt (verhindert \u00fcberm\u00e4\u00dfigen Leerraum zwischen Titel und Spielzeit)<\/li>\n\n\n\n<li><strong>Mindesth\u00f6he Player-Widget<\/strong>: 380 px (zuvor 420 px)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.67 \u2014 Crash-Handler, Media-Tasten, Bugfixes (2026-05-01)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neu: Crash-Handler (BL-103)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Modul <code>crash_handler.py<\/code>: f\u00e4ngt unbehandelte Python-Exceptions automatisch ab<\/li>\n\n\n\n<li>Bei jedem Absturz wird <code>crash_YYYYMMDD_HHMMSS.log<\/code> im App-Verzeichnis gespeichert<\/li>\n\n\n\n<li>Log enth\u00e4lt: Zeitstempel, Song, Lokation, vollst\u00e4ndiger Stacktrace, die letzten 25 Benutzeraktionen (Ring-Buffer)<\/li>\n\n\n\n<li>Beim n\u00e4chsten App-Start erscheint ein Hinweis-Dialog mit \u201eProtokoll anzeigen&#8220;-Button (\u00f6ffnet Texteditor)<\/li>\n\n\n\n<li>Geloggte Aktionen: Song aus Liste geladen, Song aus Playlist geladen, Play gestartet, Lokation gewechselt, Planner Confirm<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Media- und Fn-Tasten als Rule-Trigger<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Volume+, Volume\u2212, Mute, Media Play\/Pause, Media Stop, Media Next, Media Previous, Brightness+, Brightness\u2212 sind jetzt als Trigger in der Rule Engine verf\u00fcgbar<\/li>\n\n\n\n<li>Abfang per App-weitem EventFilter (analog zu F13\u2013F24) \u2014 funktioniert wenn das OS die Tasten nicht systemweit schluckt<\/li>\n\n\n\n<li>Neues Diagnoseskript <code>2_Test\/key_monitor.py<\/code> (+ <code>.bat<\/code>): zeigt f\u00fcr jede gedr\u00fcckte Taste Key-Code, Trigger-Name und ob Callers Caddy sie verarbeiten w\u00fcrde \u2014 hilfreich beim Einrichten von Stream Deck \/ Funk-Fernbedienungen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Statistik-Dock: Kontextmen\u00fc (BL-102)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rechtsklick auf einen Song in den Listen TOP \/ FLOP \/ Nie gespielt \u00f6ffnet ein Kontextmen\u00fc<\/li>\n\n\n\n<li><strong>\u201eZur Playlist hinzuf\u00fcgen&#8220;<\/strong> \u2192 Song landet direkt in der aktuellen Playlist<\/li>\n\n\n\n<li><strong>\u201eZu Notizen hinzuf\u00fcgen&#8220;<\/strong> \u2192 f\u00fcgt einen <code>[load_song \"Titel\"]<\/code>-Shortcode als neue Notiz ein<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>TIC-0019<\/strong> Planner: Loop-Daten wurden nach Rule-Ausf\u00fchrung nicht aktualisiert \u2014 Loop-Anzahl-Dialog liest Daten jetzt frisch aus der DB<\/li>\n\n\n\n<li><strong>TIC-0020<\/strong> Tanzprogramme verwalten: Spaltenheader \u201eZiel-Dauer (min)&#8220; wurde abgeschnitten \u2014 Spalte passt sich jetzt automatisch an den Header-Text an<\/li>\n\n\n\n<li><strong>TIC-0021<\/strong> Statistik-Dock: alternierende Zeilenfarben hatten zu wenig Kontrast \u2014 <code>alternate-background-color<\/code> jetzt f\u00fcr alle 4 Skins definiert<\/li>\n\n\n\n<li>Statistik-Dock \u2192 \u201eZu Notizen hinzuf\u00fcgen&#8220; crashte wenn das Notizen-Dock noch nie ge\u00f6ffnet war (<code>notes_widget<\/code> noch nicht lazy-initialisiert) \u2014 Fix: synchrone Init vor dem Zugriff (vom Crash-Handler in der eigenen Sitzung gefunden)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.66 \u2014 Bugfixes (TIC-0015, TIC-0017, TIC-0018) (2026-04-30)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>TIC-0015<\/strong> Lyrics-Zoom-Stufe wird jetzt beim App-Start korrekt wiederhergestellt \u2014 Zoom-Wert und Auto-Size-Zustand werden in der INI gespeichert und beim n\u00e4chsten Start sofort angewendet<\/li>\n\n\n\n<li><strong>TIC-0017<\/strong> Loop-Count-Dialog im Planner findet Songs jetzt auch in Musikordnern Slot 2\u20134 \u2014 Funktion <code>show_loop_count_dialog<\/code> nutzt jetzt <code>find_song_file()<\/code> statt nur Slot 1<\/li>\n\n\n\n<li><strong>TIC-0018<\/strong> Rule-Aktion \u201eLoad Layout&#8220;: Dropdown zeigt jetzt alle gespeicherten Layouts aus dem <code>skins\/<\/code>-Ordner \u2014 <code>layout_names_provider<\/code> angebunden, TODO-Stub ersetzt<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.65 \u2014 Statistik-Dock (BL-019) (2026-04-29)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neues Dock: Statistik<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues andockbares, lazy geladenes Fenster \u201eStatistik&#8220; im Ansicht-Men\u00fc (tabbiert mit Reports)<\/li>\n\n\n\n<li><strong>Filter<\/strong> (oben): Lokation (Alle oder einzelne), Typ (Beide \/ Pattern \/ Singing), Zeitraum (Alle Zeit \/ 5 Jahre \/ 1 Jahr \/ 3 Monate \/ 1 Monat)<\/li>\n\n\n\n<li><strong>Drei Spalten<\/strong> (scrollbar, alle Songs ohne Limit):<\/li>\n\n\n\n<li><strong>TOP<\/strong> \u2014 alle gespielten Songs, meistgespielt zuerst, mit Abspielanzahl<\/li>\n\n\n\n<li><strong>FLOP<\/strong> \u2014 alle gespielten Songs, wenigstgespielt zuerst, mit Abspielanzahl<\/li>\n\n\n\n<li><strong>Nie gespielt<\/strong> \u2014 alle Songs ohne Play in den aktuellen Filtern, alphabetisch<\/li>\n\n\n\n<li><strong>Doppelklick<\/strong> auf einen Song springt direkt zur Songliste<\/li>\n\n\n\n<li><strong>Histogramm<\/strong> (volle Breite): Verteilung aller Songs nach Abspielanzahl<\/li>\n\n\n\n<li>Bin 0 ist immer fest f\u00fcr \u201enie gespielt&#8220;, danach 9 logarithmisch verteilte Bins<\/li>\n\n\n\n<li>Farbgradient von Blau (kalt = selten) bis Orange-Rot (hei\u00df = oft gespielt), unabh\u00e4ngig vom Skin<\/li>\n\n\n\n<li>Tooltip auf jedem Balken zeigt Bin-Bereich, Anzahl Songs und bis zu 5 Beispiel-Titel<\/li>\n\n\n\n<li>\u00dcbersetzungen DE + EN vollst\u00e4ndig vorhanden<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.64 \u2014 First-Steps-Paket, Tutorial-\u00dcberholung, Playlist-Verbesserungen (2026-04-28)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Beispielprojekt f\u00fcr Neueinsteiger (first-steps\/)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>first-steps\/-Ordner<\/strong> wird in jeder Neuinstallation mitgeliefert<\/li>\n\n\n\n<li>Enth\u00e4lt \u201eYRR 049 &#8211; Electro Blues.mp3&#8243; von Jon Hansell Nilsson (freundlicherweise zur Verf\u00fcgung gestellt) und das passende Lyricsheet \u201eYRR 049 &#8211; Electro Blues.htm&#8220;. <a href=\"https:\/\/hansellnilsson.wixsite.com\/yellowrockrecords\" target=\"_blank\" rel=\"noreferrer noopener\">Yellow Rock Records<\/a> bietet kostenlose Pattern-Musik an. Unbedingt ausprobieren.<\/li>\n\n\n\n<li>Das Lyricsheet thematisiert auf witzige Weise die Funktionen von Callers Caddy<\/li>\n\n\n\n<li><code>build.py<\/code>: Schritt 3 kopiert <code>1_Source\/first-steps\/<\/code> automatisch in den App-Ordner<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tutorial: New Songs Tour (komplett \u00fcberarbeitet)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Umbenannt<\/strong> von \u201eLoop-Tour&#8220; zu \u201eNew Songs Tour&#8220;<\/li>\n\n\n\n<li><strong>Men\u00fcreihenfolge<\/strong>: New Songs Tour jetzt direkt nach Player-Tour (Prio 97), <a href=\"https:\/\/callerscaddy.de\/loop-finder\/\">Loop Finder direkt darunter<\/a> (Prio 96), Beat Snap danach<\/li>\n\n\n\n<li><strong>Step 1<\/strong> (Import-Button): Expliziter Handlungsaufruf mit Schritt-f\u00fcr-Schritt-Anleitung durch die drei Import-Dialoge \u2014 Songtyp \u201eBeides&#8220;, Kopieren, Einzeldateien aus first-steps\/<\/li>\n\n\n\n<li><strong>Step 2<\/strong> (Auto-Loop): Loop Finder als zweiter Schritt statt manuellem In\/Out-Setzen \u2014 manuelle Buttons und Beat Snap aus dem Tutorial entfernt<\/li>\n\n\n\n<li><strong>Song-Daten-Tutorial<\/strong> um Step 4 erweitert: \u201eLyricsheet verkn\u00fcpfen&#8220; mit Hinweis auf first-steps-HTM<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Songliste: Song zur Playlist hinzuf\u00fcgen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u2192 Playlist-Button<\/strong> unterhalb der Songliste (neben \u201eListe aktualisieren&#8220; und \u201e\u2192 Notiz&#8220;)<\/li>\n\n\n\n<li><strong>Rechtsklick-Kontextmen\u00fc<\/strong> der Songliste: neuer Eintrag \u201eZur Playlist hinzuf\u00fcgen&#8220;<\/li>\n\n\n\n<li>\u201e\u2192 Notiz&#8220;-Button von der Suchzeile nach unten in die Button-Leiste verschoben<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Playlist: Songs entfernen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u2715-Button<\/strong> neben den Pfeiltasten \u25b2 \u25bc entfernt den markierten Song sofort<\/li>\n\n\n\n<li><strong>Rechtsklick-Kontextmen\u00fc<\/strong>: \u201eAus Playlist entfernen&#8220; ganz oben (vor Separator)<\/li>\n\n\n\n<li><strong>Entf-Taste<\/strong>: QShortcut mit <code>WidgetWithChildrenShortcut<\/code>-Kontext \u2014 funktioniert unabh\u00e4ngig davon, welches Kind-Widget Fokus hat<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.63 \u2014 LoopFinder Lazy Init, Mapping Export\/Import, Sequenzen Export (2026-04-27)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">LoopFinder: Lazy Initialisierung<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>LoopFinderWidget<\/code> wird nicht mehr beim Start erstellt, sondern erst beim ersten \u00d6ffnen des Fensters<\/li>\n\n\n\n<li>Spart ~100ms Startzeit auf schwacher Hardware (Notebook: addDockWidget war 106ms)<\/li>\n\n\n\n<li>Waveform + Sprungbereiche werden beim \u00d6ffnen sofort angezeigt (kein manuelles \u201eAnalysieren&#8220; n\u00f6tig f\u00fcr die Vorschau)<\/li>\n\n\n\n<li>Song-Info wird nachgereicht falls beim \u00d6ffnen bereits ein Song geladen ist<\/li>\n\n\n\n<li><code>setFloating<\/code> und <code>restoreGeometry<\/code> des Dock-Fensters ebenfalls per <code>QTimer.singleShot<\/code> nach <code>show()<\/code> verschoben<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Mapping Export\/Import (Sequenzen-Men\u00fc)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Mapping exportieren\u2026<\/strong>: Speichert alle <code>call_text_mappings<\/code> als JSON-Datei (<code>call_text<\/code>, <code>entity_id<\/code>, <code>mapped_by<\/code>)<\/li>\n\n\n\n<li><strong>Mapping importieren\u2026<\/strong>: Liest JSON, f\u00fcgt neue Eintr\u00e4ge ein (<code>INSERT OR IGNORE<\/code>), \u00fcberspringt bereits vorhandene<\/li>\n\n\n\n<li>R\u00fcckmeldung: \u201eX neue Mappings importiert, Y bereits vorhanden (\u00fcbersprungen)&#8220;<\/li>\n\n\n\n<li>Bei neuen Eintr\u00e4gen wird automatisch Remapping angesto\u00dfen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sequenzen exportieren (JSON)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Men\u00fcpunkt <strong>Sequenzen exportieren (JSON)\u2026<\/strong> nach den drei Import-Punkten<\/li>\n\n\n\n<li>Exportiert alle Sequenzen im exakt gleichen Format wie der JSON-Import erwartet (<code>id<\/code>, <code>calls<\/code>, <code>level<\/code>, <code>seq_type<\/code>, <code>difficulty<\/code>)<\/li>\n\n\n\n<li>Exportierte Datei kann direkt wieder per \u201eSequenzen importieren (JSON)&#8220; eingelesen werden<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">UI-Detail<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pfeil-Buttons (\u25c0 \u25b6) und Note-Button im Sequence-Detail-Fenster haben jetzt einheitliche H\u00f6he (40px) \u2014 bessere Treffsicherheit am Laptop<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Projektdokumentation<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>CLAUDE.md<\/code>: <code>setFloating(True)<\/code> auf Windows kostet ~90ms (einmalig pro Floating-Dock-Kontext) \u2014 wandert nur zwischen Buckets wenn man es defer&#8217;t, spart keine Gesamtzeit<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.62 \u2014 CallMatcher &amp; Sequenz-UI-Verbesserungen (2026-04-27)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Call-Mapping: Intelligenter Auto-Vorschlag (CallMatcher)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Drei-Stufen-Matching vollst\u00e4ndig in <code>sequence_mapper.py<\/code> ausgelagert \u2014 keine API-Kosten, l\u00e4uft lokal in Millisekunden<\/li>\n\n\n\n<li><strong>Stufe 1<\/strong>: Exakter Vergleich nach Normalisierung (Pr\u00e4fixe\/Suffixe entfernt) \u2192 Score 1.0<\/li>\n\n\n\n<li><strong>Stufe 2<\/strong>: Bidirektionaler Token-Overlap (geometrisches Mittel aus Precision \u00d7 Recall) \u2192 Score bis 0.92<\/li>\n\n\n\n<li><strong>Stufe 3<\/strong>: <code>difflib.SequenceMatcher<\/code> als Fallback (nur wenn Token-Score \u2265 0.30) \u2192 Score bis 0.85<\/li>\n\n\n\n<li><strong>Farbcodierung<\/strong> der Call-Text-Zeilen im Mapping-Dialog:<\/li>\n\n\n\n<li>\ud83d\udfe2 Gr\u00fcn (Score \u2265 0.85): sicherer Vorschlag<\/li>\n\n\n\n<li>\ud83d\udfe1 Gelb (Score 0.50\u20130.84): unsicherer Vorschlag, manuelle Pr\u00fcfung empfohlen<\/li>\n\n\n\n<li>\ud83d\udd34 Rot (Score &lt; 0.50): kein brauchbarer Vorschlag<\/li>\n\n\n\n<li>Gr\u00fcn auch f\u00fcr bereits gemappte Eintr\u00e4ge<\/li>\n\n\n\n<li>Altes <code>_normalize_call_text<\/code>\/<code>_norm_index<\/code>-System in <code>main.py<\/code> durch <code>CallMatcher<\/code>-Import ersetzt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sequenz-Tabelle: UX-Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Level-, Type- und Difficulty-Spalten <strong>ausgeblendet<\/strong> (<code>setColumnHidden<\/code>) \u2014 Sequenz f\u00fcllt die volle Tabellenbreite<\/li>\n\n\n\n<li>Type-Filter-Dropdown startet mit <strong>\u201eSinger (Corner progression)&#8220;<\/strong> als Standardwert (h\u00e4ufigster Typ)<\/li>\n\n\n\n<li>Bugfix: <code>ResizeToContents<\/code> bei Type-Spalte lie\u00df die Sequenz-Spalte schrumpfen wenn viele Zeilen denselben langen Typ hatten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance-Logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Messpunkte: <code>SequencesWidget<\/code> und <code>SequenceViewWidget<\/code> getrennt gemessen<\/li>\n\n\n\n<li>Neuer Messpunkt: <code>_build_menu<\/code> (war bisher in <code>song_list.refresh<\/code> versteckt)<\/li>\n\n\n\n<li>Neuer Messpunkt: <code>_init_sequences<\/code> intern aufgeteilt (<code>load_sequences<\/code> + <code>sequence_view prefill<\/code>)<\/li>\n\n\n\n<li>Bugfix: LoopFinder-Split zeigte f\u00e4lschlicherweise Notizen-Zeit mit an (<code>_td10<\/code> \u2192 <code>_td10b<\/code>)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.61 \u2014 Sequenzen Import &amp; Call-Mapping (2026-04-26)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Sequenz-Tabelle erweitert<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Spalten <code>type<\/code> und <code>difficulty<\/code> in der <code>sequences<\/code>-Tabelle (Migration idempotent)<\/li>\n\n\n\n<li><code>insert_sequence()<\/code> nimmt jetzt <code>seq_type<\/code> und <code>difficulty<\/code> entgegen<\/li>\n\n\n\n<li>Neue DB-Methoden: <code>get_sequence_type_values()<\/code>, <code>get_sequence_difficulty_values()<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sequenz-UI erweitert<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tabelle: von 3 auf 4 Spalten \u2014 <strong>Sequenz<\/strong> (Stretch, sofort sichtbar), Level, Typ, Schwierigkeit<\/li>\n\n\n\n<li>Zweite Filter-Zeile mit <strong>Typ<\/strong>&#8211; und <strong>Schwierigkeit<\/strong>-Dropdown<\/li>\n\n\n\n<li>Alle Filter (Contains, Limit, Typ, Difficulty) greifen konsistent in Tabelle, Navigation und Shortcodes<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Import-Formate im Men\u00fc \u201eSequenzen&#8220;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JSON-Import<\/strong> (<code>import_from_json<\/code>): l\u00e4dt eine oder mehrere JSON-Dateien, h\u00e4ngt Sequenzen an<\/li>\n\n\n\n<li><strong>CSDS-Import<\/strong> (<code>import_from_csds<\/code>): l\u00e4dt Vic Ceder&#8217;s <code>.in<\/code>\/<code>.csds<\/code>-Exportformat; parst <code>#EASY#<\/code>\/<code>#REC=<\/code>\/<code>#SEQTYPE=<\/code>-Metadaten und bereinigt <code>&lt;C ALT=\"...\"&gt;text&lt;\/C&gt;<\/code>-Markup automatisch<\/li>\n\n\n\n<li>Deduplizierung \u00fcber Ceder-Record-ID beim Mehrfach-Import<\/li>\n\n\n\n<li>Letztes Import-Verzeichnis wird in den Settings gemerkt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Call-Mapping-Dialog<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Men\u00fcpunkt <strong>\u201eCall-Mapping\u2026&#8220;<\/strong> im Sequenzen-Men\u00fc<\/li>\n\n\n\n<li>Tabelle aller ungemappten Call-Texte, sortiert nach <strong>H\u00e4ufigkeit<\/strong> (h\u00e4ufigste zuerst \u2014 ein Eintrag kann viele Sequenzen auf einmal heilen)<\/li>\n\n\n\n<li>Rechte Spalte: editierbare ComboBox mit Contains-Autocomplete \u2014 \u00f6ffnet sich erst beim Klick (Delegate, kein Voraus-Rendering)<\/li>\n\n\n\n<li><strong>Lazy Loading<\/strong>: nur 20 Zeilen initial, weitere beim Scrollen ans Ende<\/li>\n\n\n\n<li>Gelbe Markierung f\u00fcr Texte ohne Auto-Vorschlag<\/li>\n\n\n\n<li><strong>Auto-Vorschlag<\/strong> durch normalisierten Textvergleich: Pr\u00e4fixe (Heads\/Sides\/Centers\/Boys\/Girls\u2026) und Suffixe (Zahlen, Br\u00fcche, Klammern) werden abgeschnitten<\/li>\n\n\n\n<li>Sonderoption <strong>\u201e\u2192 An Komma aufteilen&#8220;<\/strong>: Calls wie <code>\"Flutter Wheel, Sweep 1\/4\"<\/code> werden direkt in den Sequenzen gesplittet \u2014 nachfolgende Felder r\u00fccken automatisch nach rechts<\/li>\n\n\n\n<li>Sondereintrag <strong>\u201eFiller Words&#8220;<\/strong> (TO=0.001) f\u00fcr F\u00fcllphrosen die kein echtes Level haben \u2014 verhindert NULL bei der Levelberechnung ohne das Ergebnis zu verf\u00e4lschen<\/li>\n\n\n\n<li>Nach dem Speichern wird automatisch <code>recompute_sequence_max_to()<\/code> angesto\u00dfen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.60 \u2014 F13\u2013F24 Tasten-Trigger (2026-04-25)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Erweiterte F-Tasten-Unterst\u00fctzung<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>F13\u2013F24<\/strong> sind jetzt vollwertige Rule-Trigger \u2014 erscheinen im Trigger-Dropdown des Rule-Editors<\/li>\n\n\n\n<li>Capture-Dialog erkennt F13\u2013F24 beim Dr\u00fccken korrekt und zeigt sie als \u201eF13&#8243; etc. an<\/li>\n\n\n\n<li>Abfang \u00fcber den App-weiten EventFilter (zuverl\u00e4ssiger als QKeySequence-Strings, die Qt f\u00fcr F13+ nicht parst)<\/li>\n\n\n\n<li>N\u00fctzlich f\u00fcr USB-Fernbedienungen und Makro-Pads, die erweiterte F-Tasten senden<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.59 \u2014 Shortcodes in Notizen &amp; Rule-Editor Gruppen (2026-04-24)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Shortcodes in Notizen (BL-093)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Shortcode-Syntax<\/strong> in Notizen: <code>[load_song \"Titel\"]<\/code> l\u00e4dt ein Lied; <code>[sequence_view id=42]<\/code> \/ <code>[sequence_view contains=\"Swing Thru\" limit=\"MS\"]<\/code> \u00f6ffnet die Sequenzansicht mit optionalem Filter<\/li>\n\n\n\n<li>Shortcodes werden ausgel\u00f6st beim <strong>manuellen Abhaken<\/strong> einer Notiz sowie via <code>notes_tick_top<\/code>-Regel<\/li>\n\n\n\n<li>Neues Modul <code>shortcode_parser.py<\/code> mit robustem Regex-Parser (positionale und benannte Parameter, Integer-Erkennung)<\/li>\n\n\n\n<li><strong>\u2192 Notiz Button<\/strong> in Songliste, Playlist, Sequenz-\u00dcbersicht und Sequenz-Detail: f\u00fcgt den aktuellen Eintrag als Shortcode in die Notizliste ein<\/li>\n\n\n\n<li><strong>\u2192 Filter Button<\/strong> in Sequenz-\u00dcbersicht: f\u00fcgt die aktiven Contains\/Limit-Filter als <code>[sequence_view]<\/code>-Shortcode ein<\/li>\n\n\n\n<li><strong>Rechtsklick-Men\u00fc<\/strong> (Context-Menu) in Songliste, Playlist und Sequenz-Tabelle: \u201eZu Notizen hinzuf\u00fcgen&#8220;<\/li>\n\n\n\n<li>Warnung wenn keine Lokation gew\u00e4hlt und Notiz eingef\u00fcgt werden soll<\/li>\n\n\n\n<li>Songtitel wird ohne Anzeige-Suffixe (Typ, Label, Qualit\u00e4t) in den Shortcode \u00fcbernommen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rule-Editor: Aktionen gruppiert<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die 43 Regelaktionen sind jetzt in <strong>10 Kategorien<\/strong> gegliedert: Transport \u00b7 Audio \u00b7 Layout &amp; Docks \u00b7 Lyrics &amp; Scroll \u00b7 Sequence View \u00b7 Notes \u00b7 Workflow \u00b7 Photo \u00b7 Genre \u00b7 Info &amp; Warnings<\/li>\n\n\n\n<li>Nicht-ausw\u00e4hlbare Gruppenheader im Aktions-Dropdown f\u00fcr bessere \u00dcbersicht<\/li>\n\n\n\n<li>Reihenfolge der Aktionen innerhalb der Gruppen logisch sortiert<\/li>\n\n\n\n<li>Bestehende Rules bleiben vollst\u00e4ndig kompatibel \u2014 nur die Anzeige \u00e4ndert sich<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.58 \u2014 Sequence Detail als echtes Dock (2026-04-24)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Sequence Detail als QDockWidget (BL-092)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>dock_sequence_view<\/code><\/strong> ist jetzt ein vollwertiges Dock-Widget \u2014 kein tempor\u00e4rer Popup-Dialog mehr<\/li>\n\n\n\n<li>Kann wie alle anderen Docks behandelt werden: <code>dock_open<\/code>, <code>dock_close<\/code>, <code>dock_fullsize<\/code>, <code>dock_focus<\/code>, <code>dual_view<\/code>, Layout-Save\/Restore<\/li>\n\n\n\n<li>Klick auf eine Zeile in der Sequenz\u00fcbersicht aktualisiert das Detail-Dock und bringt es in den Vordergrund<\/li>\n\n\n\n<li>Im Regel-Editor unter dem Kurzname <strong><code>sequence_view<\/code><\/strong> verf\u00fcgbar (z.B. <code>dual_view<\/code> mit <code>dock_left=sequences<\/code> + <code>dock_right=sequence_view<\/code>)<\/li>\n\n\n\n<li><code>sequenceview_maximize<\/code> \u00f6ffnet das Dock als schwebendes 90 %-Fenster \u2014 kein Konflikt mehr mit dem Dual-View<\/li>\n\n\n\n<li>Navigation (\u25c0\/\u25b6, Tastatur \u2190 \u2192) bleibt erhalten; <code>sequenceview_prev<\/code>\/<code>sequenceview_next<\/code>-Regelaktionen steuern das Dock direkt<\/li>\n\n\n\n<li>Alle Regel-Aktionsnamen durchgehend Englisch: <code>sequenceview_*<\/code> (statt <code>sequenzview_*<\/code>)<\/li>\n\n\n\n<li><strong>Filter-Sync<\/strong>: \u00c4ndert der Nutzer den Contains- oder Limit-Filter in der Sequenz\u00fcbersicht, springt das Detail-Dock automatisch auf die erste Sequenz der neuen Ergebnisliste (nur wenn das Dock sichtbar ist)<\/li>\n\n\n\n<li><strong>Startup-Vorbef\u00fcllung<\/strong>: Beim App-Start wird das Detail-Dock sofort mit Sequenz 1 gef\u00fcllt \u2014 kein leeres Fenster beim ersten \u00d6ffnen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.57 \u2014 SequenzView Navigation &amp; Vollbild (2026-04-24)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">SequenzView \u2014 Navigation ohne Dialog zu schlie\u00dfen (BL-089)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u2039 \/ \u203a Buttons<\/strong> in der Sequenzansicht: bl\u00e4ttert durch die aktuell gefilterte Liste<\/li>\n\n\n\n<li><strong>Positions-Anzeige<\/strong> \u201e3 \/ 12&#8243; zwischen den Buttons \u2014 Caller sieht sofort wo er in der Liste steht<\/li>\n\n\n\n<li><strong>Tastatur-Support<\/strong>: \u2190 \/ \u2192 Pfeiltasten navigieren ebenfalls (ideal f\u00fcr freihandigen Betrieb)<\/li>\n\n\n\n<li>Buttons werden am Anfang bzw. Ende der Liste automatisch deaktiviert<\/li>\n\n\n\n<li>Navigation bezieht sich immer auf die vollst\u00e4ndige gefilterte Liste (nicht nur geladene Zeilen)<\/li>\n\n\n\n<li>Neue DB-Methode <code>get_filtered_sequence_ids()<\/code> liefert alle passenden IDs f\u00fcr die Navigation<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">SequenzView \u2014 Auto-Zoom &amp; freie Fenstergr\u00f6\u00dfe (BL-090)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Frei vergr\u00f6\u00dferbar<\/strong>: Dock kann beliebig gro\u00df gezogen werden<\/li>\n\n\n\n<li><strong>Mitwachsende Schrift<\/strong>: Schriftgr\u00f6\u00dfe der Calls passt sich automatisch an die verf\u00fcgbare Fensterh\u00f6he an \u2014 Sequenz f\u00fcllt das Fenster optimal aus<\/li>\n\n\n\n<li><strong>\u25c0 \/ \u25b6 Buttons<\/strong> in einheitlicher Gr\u00f6\u00dfe (font-size 16px)<\/li>\n\n\n\n<li><strong>Position-Label<\/strong> \u201eX \/ N&#8220; verwendet die Schriftfarbe des aktiven Themes<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">SequenzView \u2014 Rule-Aktionen (BL-091)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>sequenzview_open<\/code><\/strong>: zeigt das Detail-Dock mit der aktuellen Tabellenauswahl<\/li>\n\n\n\n<li><strong><code>sequenzview_close<\/code><\/strong>: versteckt das Detail-Dock<\/li>\n\n\n\n<li><strong><code>sequenzview_prev<\/code> \/ <code>sequenzview_next<\/code><\/strong>: bl\u00e4ttert per Rule\/<a href=\"https:\/\/callerscaddy.de\/press-any-key\/\">Tastenk\u00fcrzel zur vorherigen<\/a>\/n\u00e4chsten Sequenz<\/li>\n\n\n\n<li><strong><code>sequenzview_focus<\/code><\/strong>: bringt das Detail-Dock in den Vordergrund<\/li>\n\n\n\n<li><strong><code>sequenzview_maximize<\/code><\/strong>: macht das Detail-Dock als schwebendes 90%-Fenster<\/li>\n\n\n\n<li><strong>Auto-Zoom bidirektional<\/strong>: Schriftgr\u00f6\u00dfe wird auch nach oben korrigiert wenn der erste Sch\u00e4tzwert zu konservativ war<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.56 \u2014 Dual-View &amp; Songlisten-Schnellnavigation (2026-04-23)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Dual-View: zwei Widgets nebeneinander (BL-077)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neue Regel-Aktion <code>dual_view<\/code><\/strong>: \u00d6ffnet zwei beliebige Docks als schwebende Fenster nebeneinander \u2014 zusammen 90 % Bildschirmbreite und -h\u00f6he, zentriert mit 4 px Abstand<\/li>\n\n\n\n<li><strong>Flexibles Breitenverh\u00e4ltnis<\/strong>: Auswahl aus <code>50:50<\/code>, <code>33:67<\/code> oder <code>67:33<\/code> direkt im Regel-Editor<\/li>\n\n\n\n<li><strong>Neue Aktion <code>dual_view_close<\/code><\/strong>: Schlie\u00dft beide Dual-View-Fenster und dockt sie zur\u00fcck<\/li>\n\n\n\n<li><strong>Neue Aktion <code>dual_view_toggle<\/code><\/strong>: <a href=\"https:\/\/callerscaddy.de\/dual-view\/\">Ein Tastendruck \u00f6ffnet den Dual-View<\/a> (Layout wird automatisch gesichert), ein zweiter Tastendruck stellt das urspr\u00fcngliche Layout exakt wieder her \u2014 ideal als Keyboard-Shortcut<\/li>\n\n\n\n<li>Alle drei Aktionen erscheinen mit englischen Display-Namen im Regel-Editor; Parameter <code>dock_left<\/code>, <code>dock_right<\/code> und <code>split<\/code> als gewohnte Dropdowns<\/li>\n\n\n\n<li>H\u00e4ufigste Kombination: Lyrics links + Sequenzen rechts, 50:50<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.55 \u2014 Planner-Loop-Dialog &amp; Doppelklick-Fix (2026-04-22)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Planner: Loop-Dialog mit Ziel-Patternl\u00e4nge vorbelegt (BL-085)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Loop-Count-Dialog<\/strong> im Planner und im Playlist-Widget \u00fcbernimmt jetzt automatisch die Ziel-Patternl\u00e4nge des aktiven Tanzprogramms als Voreinstellung (statt fest 7 min)<\/li>\n\n\n\n<li>Ist kein Tanzprogramm gesetzt, bleibt der Standardwert 7 min<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Playlist-Widget: Doppelklick auf Loops-Spalte (BL-085)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Doppelklick auf die Loops-Spalte<\/strong> im Playlist-Dock \u00f6ffnet jetzt denselben Loop-Count-Dialog wie im Planner \u2014 Anzahl und Zeitvorgabe direkt editierbar<\/li>\n\n\n\n<li>Zuverl\u00e4ssige Ausl\u00f6sung \u00fcber <code>mouseDoubleClickEvent<\/code>-Override in <code>_PlaylistTable<\/code>, der einen bekannten Qt-6-Timing-Konflikt zwischen DragDrop-Modus und <code>cellDoubleClicked<\/code>-Signal umgeht<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">0.54 \u2014 Tanzprogramm-System &amp; Lokations-Erweiterungen (2026-04-22)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Tanzprogramm-Anzeige im Player (BL-083)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer Button <code>btn_program<\/code><\/strong> in der Player-Info-Zeile (neben BPM): zeigt das aktuell eingestellte Tanzprogramm-K\u00fcrzel an (z.B. <code>MS<\/code>, <code>A1 Class<\/code>)<\/li>\n\n\n\n<li><strong>Schnellauswahl-Dialog<\/strong>: Klick auf den Button \u00f6ffnet ein Grid aller konfigurierten Programme als Schaltfl\u00e4chen \u2014 Button-Breite passt sich automatisch an den l\u00e4ngsten Text an<\/li>\n\n\n\n<li><strong>14 Default-Programme<\/strong>: MS, MS Class, PL, PL Class, A1, A1 Class, A2, A2 Class, C1, C1 Class, C2, C2 Class, C3A, C3A Class \u2014 je mit konfigurierbarer Ziel-Patternl\u00e4nge (Standard 7 min)<\/li>\n\n\n\n<li><strong>Verwaltungsdialog<\/strong> \u00fcber Men\u00fc <em>Datenbank \u2192 Tanzprogramme verwalten<\/em>: Programme anlegen, umbenennen, Reihenfolge und Ziel-Patternl\u00e4nge anpassen, l\u00f6schen<\/li>\n\n\n\n<li>Neue DB-Tabelle <code>dance_programs<\/code>; bestehende Installationen erhalten die Default-Programme automatisch beim n\u00e4chsten Start (INSERT OR IGNORE)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Lokations-Einstellungen: Tanzprogramm &amp; tempor\u00e4res Tempo (BL-084 + BL-086)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer \u201eEinstellungen&#8220;-Button<\/strong> im Lokations-Dialog: \u00f6ffnet einen Einstellungs-Dialog f\u00fcr die gew\u00e4hlte Lokation<\/li>\n\n\n\n<li><strong>Tanzprogramm-Zuweisung pro Lokation<\/strong>: Beim W\u00e4hlen einer Lokation wird das gespeicherte Tanzprogramm automatisch im Player eingestellt<\/li>\n\n\n\n<li><strong>Tempor\u00e4res Tempo pro Lokation<\/strong>: SpinBox (50\u2013150 %, Standard 100 % = kein Einfluss). Bei Lokationswechsel wird der gespeicherte Wert automatisch in das Feld \u201eTempor\u00e4res Tempo&#8220; \u00fcbernommen \u2014 praktisch f\u00fcr Classes und Anf\u00e4nger-Gruppen mit fester Tempobremse<\/li>\n\n\n\n<li>Neue DB-Spalten <code>dance_program_id<\/code> und <code>temp_tempo<\/code> in der <code>locations<\/code>-Tabelle (Migration f\u00fcr Bestandsinstallationen)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.53 \u2014 Class Designer: Pr\u00fcfen &amp; Optimieren, Notizen-Feinschliff (2026-04-20)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Class Designer \u2014 Pr\u00fcfen &amp; Optimieren (neu)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u201ePr\u00fcfen&#8220;-Button<\/strong> in Spalte 3: l\u00f6st explizit \u00dcberlast\/Unterlast-F\u00e4rbung der Tagesheader und Abstandregel-Check aus<\/li>\n\n\n\n<li><strong>Orange Markierung<\/strong> f\u00fcr Teaches, die Prereq-Delay-Regeln verletzen (vorher rot) \u2014 klar abgegrenzt vom roten \u00dcberlast-Tagesheader<\/li>\n\n\n\n<li><strong>\u201eOptimieren&#8220;-Button<\/strong>: iterative Local Search (Best-Improvement Hill Climbing) auf dem bestehenden Plan \u2014 ersetzt keine Generator-Neubelegung, sondern r\u00e4umt Verst\u00f6\u00dfe und Lastungleichheiten nachtr\u00e4glich auf<\/li>\n\n\n\n<li>Zielfunktion: <code>Verst\u00f6\u00dfe \u00d7 10 000 + \u03a3(Last \u2212 \u00d8)\u00b2<\/code> \u2014 Constraint-Verst\u00f6\u00dfe dominieren hart, Lastvarianz wird darunter feinabgestimmt<\/li>\n\n\n\n<li>Respektiert manuelle Drag-\u00c4nderungen in Spalte 3<\/li>\n\n\n\n<li>Harte Constraints werden pro Move gepr\u00fcft: Prereq-Delay, Nachfolger-Delay, Repeat nach Teach, keine doppelten Repeats am selben Tag<\/li>\n\n\n\n<li>Konvergiert deterministisch (max. 200 Iterationen); typisch deutlich schneller<\/li>\n\n\n\n<li>Algorithmus-Einordnung (RCPSP \/ Sprint-Rebalancing) dokumentiert in <code>docs\/16_class_designer.md<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Class Designer \u2014 UX-Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Effort-Felder als Button-Reihe<\/strong> statt ComboBox: alle Fibonacci-Werte (1, 2, 3, 5, 8, 13 bzw. 0\u201313 bei Info) als Toggle-Buttons direkt sichtbar \u2014 ein Klick statt Dropdown \u00f6ffnen<\/li>\n\n\n\n<li><strong>Neue Eintr\u00e4ge hinter markiertem Element<\/strong>: Bei \u201e+ Call&#8220; und \u201e+ Info&#8220; wird das neue Element hinter dem aktuell selektierten eingef\u00fcgt (statt ans Ende) und automatisch markiert \u2014 kettenweises Einf\u00fcgen flie\u00dft nat\u00fcrlich<\/li>\n\n\n\n<li><strong>Effort-Filter in Spalte 2<\/strong>: Toggle-Button-Reihe <code>0 | 1 | 2 | 3 | 5 | 8 | 13<\/code> zwischen Toolbar und Planungstabelle. Standardm\u00e4\u00dfig alle aktiv \u2014 erm\u00f6glicht auf einen Blick zu pr\u00fcfen, ob Calls mit gleichem Aufwand auch \u00e4hnlich aufwendig sind<\/li>\n\n\n\n<li><code>n_evenings<\/code> wird im Col3-Widget gespeichert, damit Optimieren auch nach manuellen \u00c4nderungen mit dem richtigen Rahmen arbeitet<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Notizen-Widget \u2014 Darstellung &amp; Bearbeitung<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Oberste offene Notiz 4\u00d7 vergr\u00f6\u00dfert<\/strong> (BL-079): Die aktuell wichtigste Notiz wird prominent als gro\u00dfe, fette \u00dcberschrift angezeigt \u2014 Vergr\u00f6\u00dferungsfaktor in INI konfigurierbar (<code>notes\/first_note_factor<\/code>, Default 4.0)<\/li>\n\n\n\n<li><strong>Kompakter Zeilenabstand<\/strong> bei langem Mehrzeilen-Text: Das Label rendert Wort-Umbr\u00fcche jetzt selbst (statt \u00fcber Qt&#8217;s Standard-Lineheight) und nutzt ca. 90 % der Schriftgr\u00f6\u00dfe als Zeilenvorschub \u2014 spart bei der gro\u00dfen ersten Zeile erheblich Platz, ohne Descender abzuschneiden<\/li>\n\n\n\n<li><strong>Wortumbruch<\/strong> f\u00fcr sehr lange Notizen: Text umbricht sauber innerhalb der Zeile, Zeilenh\u00f6he w\u00e4chst mit<\/li>\n\n\n\n<li><strong>Doppelklick zum Bearbeiten<\/strong>: Linker Doppelklick auf eine Notizzeile \u00f6ffnet einen Edit-Dialog mit mehrzeiligem Textfeld \u2014 Theme-konform gestylt, Sprache folgt UI-Einstellung (DE\/EN), <code>Ctrl+Enter<\/code> best\u00e4tigt<\/li>\n\n\n\n<li><strong>Zoom-Buttons +\/\u2212<\/strong> weiterhin aktiv \u2014 die neue Rendering-Logik respektiert die Zoom-Stufe<\/li>\n\n\n\n<li>Neue DB-Methode <code>update_note_text(note_id, text)<\/code> in <code>song_db<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Regel-System<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neue Aktion <code>notes_tick_top<\/code><\/strong> (BL-080): Hakt die oberste offene Notiz der aktiven Lokation ab \u2014 n\u00fctzlich z.B. f\u00fcr Keyboard-Shortcuts oder Timer-Events. Bei leerer Liste stumm ignoriert (keine Fehlermeldung)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Interne Aufr\u00e4umarbeiten<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Helper-Widget <code>_ValueButtonRow<\/code> f\u00fcr exklusive Wert-Auswahl (wiederverwendbar f\u00fcr weitere diskrete Auswahlen)<\/li>\n\n\n\n<li>Helper <code>_insert_after_selected()<\/code> in Col2 \u2014 zentralisiert Einf\u00fcge-Logik<\/li>\n\n\n\n<li>Neue QLabel-Subklasse <code>_TightLabel<\/code> mit eigenem <code>paintEvent<\/code> + manuellem Wortumbruch f\u00fcr pr\u00e4zise Zeilenabstandskontrolle<\/li>\n\n\n\n<li>Neuer modaler Dialog <code>_NoteEditDialog<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.52 \u2014 Class Designer (Prototyp) &amp; Tracking-Fix (2026-04-17)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Class Designer \u2014 Erster Prototyp<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Hinweis<\/strong>: Dies ist der <strong>erste Prototyp<\/strong> des Class Designers \u2014 weiterer Feinschliff ist definitiv n\u00f6tig<\/li>\n\n\n\n<li><strong>Gleichm\u00e4\u00dfigere Punkteverteilung pro Tag<\/strong>: Umstellung auf Greedy-Bin-Filling. Jeder Tag wird bis zum Zielbudget (Gesamt-Punkte \/ Anzahl Tage) aufgef\u00fcllt, bevor der n\u00e4chste Tag bef\u00fcllt wird<\/li>\n\n\n\n<li><strong>Repeat-Constraints respektiert<\/strong>: Wiederholungen derselben Figur halten weiterhin mind. 1 Tag Abstand; Prereq-Delays bleiben erhalten<\/li>\n\n\n\n<li><strong>Unterf\u00fcllte Tage vermieden<\/strong>: Wenn ein Repeat wegen <code>earliest<\/code>-Constraint vorspringt, bleibt der Tag-Zeiger zur\u00fcck \u2014 nachfolgende Teaches f\u00fcllen den freigebliebenen Tag auf, statt ihn leer zu lassen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Loop Finder \u2014 Zeit-Anzeige unter Suchbereichen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Spielzeiten unter den Prozent-Feldern<\/strong>: Unter jedem der 4 Prozent-Felder (Loop-In Start\/Ende, Loop-Out Start\/Ende) wird jetzt die konkrete Spielzeit des geladenen Songs im Format <code>m:ss<\/code> angezeigt (z.B. <code>0:53<\/code>). So sieht der Caller auf einen Blick, wo im Song der Suchbereich liegt<\/li>\n\n\n\n<li>Anzeige aktualisiert sich live bei Eingabe der Prozentwerte und beim Ziehen der Waveform-Handles<\/li>\n\n\n\n<li>Einheitliche Zeilenh\u00f6he: Preset-ComboBox und Load\/Save-Buttons nutzen jetzt dieselbe H\u00f6he wie die Prozent-SpinBoxen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix \u2014 Abspielhistorie<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tracking nur bei echtem Play<\/strong>: Bisher wurde die &#8222;Zuletzt gespielt&#8220;-Spalte bereits beim reinen Selektieren\/Laden einer Datei aktualisiert. Jetzt wird der Zeitstempel ausschlie\u00dflich beim tats\u00e4chlichen Dr\u00fccken von Play gesetzt. Der Song muss nicht vollst\u00e4ndig durchlaufen<\/li>\n\n\n\n<li>Der DB-Eintrag in <code>play_history<\/code> war bereits korrekt, nur die UI-Spalte lief voraus<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.51 \u2014 Notizen-Widget Verbesserungen (2026-04-15)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Notizen-Widget \u2014 \u00dcberarbeitung &amp; neue Features<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Export-Ordner <code>notes\/<\/code><\/strong>: Neuer Unterordner wird automatisch angelegt; ist Default-Ort f\u00fcr Laden\/Speichern von JSON-Dateien<\/li>\n\n\n\n<li><strong>Hintergrundfarbe<\/strong>: &#8222;Erledigt&#8220;-Liste hat jetzt dieselbe Hintergrundfarbe wie &#8222;Offen&#8220;-Liste \u2014 einheitliches Erscheinungsbild<\/li>\n\n\n\n<li><strong>Export-Markierung<\/strong>: Auswahl-Checkbox ersetzt durch <code>_SelectToggle<\/code> (\u25cb \/ \u2713) \u2014 kein Qt-QSS-Problem mehr mit unsichtbarem Haken<\/li>\n\n\n\n<li><strong>Drag-Highlight<\/strong>: Gezogene Zeile erh\u00e4lt w\u00e4hrend des Verschiebens farbigen Hintergrund + linken Rand (Akzentfarbe)<\/li>\n\n\n\n<li><strong>Alle markieren \/ Alle abw\u00e4hlen<\/strong>: Zwei neue Buttons <code>Alle \u2713<\/code> und <code>Alle \u25cb<\/code> f\u00fcr schnelle Export-Selektion<\/li>\n\n\n\n<li><strong>Zoom-Controls<\/strong>: <code>\u2212<\/code> \/ <code>100%<\/code> \/ <code>+<\/code> oben rechts \u2014 \u00e4ndert nur die Schriftgr\u00f6\u00dfe der Listeneintr\u00e4ge; Icons aus dem aktiven Skin<\/li>\n\n\n\n<li><strong>Zoom-Persistenz<\/strong>: Zoom-Einstellung wird in INI gespeichert (<code>notes\/zoom_pct<\/code>) und beim n\u00e4chsten Start wiederhergestellt<\/li>\n\n\n\n<li><strong>Zeitstempel bei Erledigt<\/strong>: Abschluss-Zeitpunkt wird im Format <code>[TT.MM.JJ HH:MM]<\/code> hinter dem Text angezeigt<\/li>\n\n\n\n<li><strong>Import-Reihenfolge<\/strong>: Aus JSON geladene Notizen werden in korrekter Reihenfolge oben eingef\u00fcgt<\/li>\n\n\n\n<li><strong>Done-Toggle<\/strong>: \u2610 (offen) \/ \u2611 (erledigt) \u2014 Stift-Experiment r\u00fcckg\u00e4ngig gemacht<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Loop Active Checkbox \u2014 Barrierefreiheit<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Sichtbarer Haken<\/strong>: Alle 4 Skin-QSS-Dateien erweitert \u2014 <code>QCheckBox::indicator:checked<\/code> zeigt jetzt wei\u00dfes H\u00e4kchen (check.svg) auf farbigem Hintergrund<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sequenzen-Widget<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Zoom-Persistenz<\/strong>: Zoom-Einstellung wird in INI gespeichert (<code>sequences\/zoom_pct<\/code>) und beim Start wiederhergestellt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Notizen-Dock lazy<\/strong>: Widget wird erst beim ersten \u00d6ffnen erstellt (wie Reports, Potential, Photo) \u2014 kein Startup-Overhead<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.50 \u2014 Frei belegbare Tasten-Trigger (2026-04-09)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Tasten-Trigger selbst erzeugen (BL-064)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Neuer Button \u201e+ Taste&#8220;<\/strong> im Rules-Dialog neben der Trigger-Auswahl<\/li>\n\n\n\n<li>Klick \u00f6ffnet Mini-Dialog: User dr\u00fcckt eine beliebige Taste \u2014 der Trigger-Name wird automatisch ermittelt<\/li>\n\n\n\n<li>Unterst\u00fctzte Tasten: A\u2013Z, 0\u20139, F1\u2013F12, Space, Return, Delete, Tab, Escape, Insert, Backspace, Home, End, PageUp, PageDown<\/li>\n\n\n\n<li>Nach dem Erstellen taucht der neue Trigger sofort in der Trigger-Liste auf und kann einer Rule zugewiesen werden<\/li>\n\n\n\n<li><strong>Persistierung<\/strong>: Neue Trigger werden automatisch beim App-Start wiederhergestellt, sofern mindestens eine Rule damit verkn\u00fcpft ist<\/li>\n\n\n\n<li><strong>Fokus-Sicherheit<\/strong>: Tasten-Trigger feuern nicht, wenn ein Textfeld oder eine Suche aktiv ist \u2014 diese haben immer Priorit\u00e4t. Gilt automatisch f\u00fcr alle zuk\u00fcnftigen Trigger.<\/li>\n\n\n\n<li><strong>Dynamischer eventFilter<\/strong>: Nicht mehr hardcodiert \u2014 alle registrierten <code>key_*<\/code>-Trigger werden automatisch erkannt und weitergeleitet<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.49 \u2014 Label-Erkennung (bidirektional), Lyrics-Co-Import (2026-04-08)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Label-Erkennung \u2014 bidirektionale Dateibenennung<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Format 1 (Titel-Label)<\/strong>: <code>Ring Of Fire-RYL818.mp3<\/code> \u2192 Titel: &#8222;Ring Of Fire&#8220;, Label: &#8222;RYL818&#8220;<\/li>\n\n\n\n<li><strong>Format 2 (Label-Titel)<\/strong>: <code>RYL818-Ring Of Fire.mp3<\/code> \u2192 Titel: &#8222;Ring Of Fire&#8220;, Label: &#8222;RYL818&#8220;<\/li>\n\n\n\n<li><strong>Mit Leerzeichen im Label<\/strong>: <code>YRR 043a-Dunderklumpen.mp3<\/code> oder <code>Dunderklumpen-YRR 043a.mp3<\/code><\/li>\n\n\n\n<li>Regex-Pattern: Buchstaben + optionales Leerzeichen + Ziffern + optionaler Suffix (a\/b\/+)<\/li>\n\n\n\n<li>Unterst\u00fctzte Label-Formate: <code>BVR113<\/code>, <code>RYL818+<\/code>, <code>YRR 043a<\/code>, <code>RBS 1326<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Lyrics-Co-Import<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim MP3-Import wird automatisch eine gleichnamige Lyrics-Datei gesucht (ohne Extension-Suffix)<\/li>\n\n\n\n<li><strong>Quellordner (Import-Ordner)<\/strong>: RTF\/HTML\/TXT-Datei wird in <code>lyrics\/<\/code>-Ordner kopiert<\/li>\n\n\n\n<li><strong>Lyrics-Ordner<\/strong>: Bereits vorhanden \u2192 wird direkt verkn\u00fcpft<\/li>\n\n\n\n<li>Unterst\u00fctzte Lyrik-Formate: <code>.rtf<\/code>, <code>.htm<\/code>, <code>.html<\/code>, <code>.txt<\/code><\/li>\n\n\n\n<li>Log-Ausgabe: <code>[Import] Lyrics verkn\u00fcpft: &lt;dateiname&gt;<\/code> bei erfolgreicher Zuordnung<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.48 \u2014 SqView-Migration, Blind-Import, Theme-Fix (2026-04-08)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">SqView-Migration (BL-011)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ordner-Auswahl<\/strong>: User w\u00e4hlt den SqView-Ordner direkt per Explorer \u2014 <code>sqview.db<\/code>, <code>MP3\/<\/code> und <code>text\/<\/code> werden automatisch erkannt<\/li>\n\n\n\n<li><strong>Blind-Import<\/strong>: Songs werden auch ohne vorhandene MP3-Dateien vollst\u00e4ndig in die DB eingetragen (Dateiname als Platzhalter). MP3s k\u00f6nnen sp\u00e4ter per normalem Datei-Import nachgeliefert werden \u2014 bestehende Eintr\u00e4ge werden automatisch aktiviert statt als Duplikat \u00fcbersprungen<\/li>\n\n\n\n<li><strong>Vollst\u00e4ndige Song-Erkennung<\/strong>: Liest alle ~200 Songs aus <code>markext1\/2\/3<\/code> + <code>track<\/code>-Tabelle (nicht nur die ~10 mit expliziten Einstellungen in der <code>music<\/code>-Tabelle)<\/li>\n\n\n\n<li><strong>Rekursiver MP3-Index<\/strong>: Durchsucht alle Unterordner (<code>patter\/<\/code>, <code>singer\/<\/code>, <code>Karaoke\/<\/code> etc.)<\/li>\n\n\n\n<li><strong>Lyrics-Matching<\/strong>: 4-stufige Regex-Strategie \u2014 exakter Titel, Label-Strip (<code>- RBS 1234<\/code>), Normalisierung (alphanumerisch), Kombination<\/li>\n\n\n\n<li><strong>Loop- und Pitch-\u00dcbernahme<\/strong>: Werte aus der SqView-<code>music<\/code>-Tabelle werden \u00fcbernommen<\/li>\n\n\n\n<li><strong>Abspielhistorie<\/strong>: Aus <code>track<\/code>-Tabelle mit Datum\/Zeit und Lokations-Zuordnung<\/li>\n\n\n\n<li>Musik-Ordner ist optional (Blind-Import l\u00e4uft auch ohne)<\/li>\n\n\n\n<li>MP3-Z\u00e4hlung in der Statusanzeige jetzt rekursiv<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Blind-Import aktivieren (Datei-Import)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim normalen MP3-Import: Existiert bereits ein DB-Eintrag zum Dateinamen, aber die Datei fehlt noch im <code>music\/<\/code>-Ordner \u2192 Datei wird kopiert und der Song aktiviert (statt als Duplikat \u00fcbersprungen)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Song Data \u2014 heller Hintergrund im Default-Theme<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>QScrollArea<\/code>-Viewport und dessen Inhalt erhielten keinen dunklen Hintergrund (Qt-Stylesheet-Vererbung greift nicht durch Viewport-Grenzen)<\/li>\n\n\n\n<li>Fix in allen 4 Themes (default, win11, elegant, light)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.47 \u2014 Loop Finder Presets, CrossFade Beat Snap (2026-04-07)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Loop Finder: Parameter-Presets (BL-046)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Preset-ComboBox<\/strong> ersetzt den alten Reset-Button: zeigt alle gespeicherten Presets, &#8222;Standard&#8220; ist nicht \u00fcberschreibbar<\/li>\n\n\n\n<li><strong>Laden<\/strong>-Button: Wendet das gew\u00e4hlte Preset auf Suchbereiche, Vergleichsfenster und Strategie an<\/li>\n\n\n\n<li><strong>Speichern<\/strong>-Button: Immer aktiv \u2014 bei &#8222;Standard&#8220; erscheint Eingabedialog f\u00fcr neuen Namen, bei User-Presets direktes \u00dcberschreiben<\/li>\n\n\n\n<li>Presets als JSON-Dateien im Ordner <code>loop_presets\/<\/code> \u2014 portabel und editierbar<\/li>\n\n\n\n<li><strong>Strategie-ComboBox<\/strong> in der Analyse-Zeile: zeigt alle verf\u00fcgbaren Auswahlstrategien (aktuell: <em>&#8222;Bestes Vielfaches von 64 Beats&#8220;<\/em>), wird mit dem Preset gespeichert und geladen; weitere Strategien jederzeit nachr\u00fcstbar<\/li>\n\n\n\n<li><strong>Rules-Aktion &#8222;Auto-Set Best Loop&#8220;<\/strong> hat jetzt Parameter <code>preset<\/code> (Dropdown aller gespeicherten Presets)<\/li>\n\n\n\n<li>L\u00e4dt Suchbereiche, Vergleichsfenster und Strategie vollst\u00e4ndig aus dem gew\u00e4hlten Preset<\/li>\n\n\n\n<li>Neuer <code>preset_choice<\/code>-Parametertyp in rule_widget.py mit <code>preset_names_provider<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">CrossFade im Beat Snap (BL-067)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Toggle-Button <strong>CrossFade<\/strong> zwischen Snap und Vorh\u00f6ren<\/li>\n\n\n\n<li>Wenn aktiv: Vorh\u00f6ren des Loop-Sprungs mit demselben Crossfade wie im Normalbetrieb<\/li>\n\n\n\n<li>Wird bei jedem Laden und jeder Waveform-\u00c4nderung automatisch deaktiviert<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Taskleisten-Icon Laptop-Fix<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>cc-logo.png<\/code> wird beim Build ins App-Root kopiert (war bisher nur auf Build-Rechner vorhanden)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.46 \u2014 Live-Volume (BL-070), UI-Gleichraster Player (2026-04-07)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Live-Volume \/ Mindest-Lautst\u00e4rke (BL-070)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer <strong>Live-Vol-Slider<\/strong> im Player (4. Spalte neben Heutiges Tempo \/ Song-Tempo \/ Pitch)<\/li>\n\n\n\n<li>Artefaktfreie Lautst\u00e4rke\u00e4nderung via Windows WASAPI (pycaw) \u2014 au\u00dferhalb des Audio-Streams, keine Knackser bei schnellen Bewegungen<\/li>\n\n\n\n<li>Reset auf 100% bei jedem Song-Wechsel (nicht persistent)<\/li>\n\n\n\n<li>INI-Einstellung <code>audio\/min_volume<\/code> (Default <code>0.0<\/code>): Slider kann nicht unter diesen Wert gesenkt werden<\/li>\n\n\n\n<li>Wird beim App-Start automatisch in INI geschrieben falls fehlend<\/li>\n\n\n\n<li>Graceful Degradation: ohne pycaw (kein Windows-Ger\u00e4t) bleibt Funktion stumm, App l\u00e4uft normal weiter<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rules-Aktion: Live-Volume \u00e4ndern<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Aktion <strong>&#8222;Change Live-Volume (\u00b1)&#8220;<\/strong> mit einstellbarem <code>delta<\/code> in Prozentpunkten (\u2212100 bis +100, Default \u221210)<\/li>\n\n\n\n<li>Respektiert automatisch die <code>min_volume<\/code>-Grenze aus der INI<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">UI: Player-Zeilen im gleichm\u00e4\u00dfigen 4er-Raster<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zeile &#8222;Heutiges Tempo \/ Song-Tempo \/ Pitch \/ Live-Vol&#8220;: <code>QGridLayout<\/code> mit <code>columnStretch=1<\/code> + <code>QSizePolicy.Ignored<\/code> \u2192 exakt gleichbreite Spalten<\/li>\n\n\n\n<li>Zeile &#8222;Lokation \/ Planner \/ Lyrics \/ Loop aktiv&#8220;: ebenfalls ins 4er-Raster \u00fcberf\u00fchrt, b\u00fcndig mit Zeile dar\u00fcber<\/li>\n\n\n\n<li>Labels mit <code>setWordWrap(True)<\/code> \u2014 kein Text bl\u00e4ht seine Spalte auf<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.45 \u2014 Genre-System, Rules Drag&amp;Drop, Bugfixes (2026-04-06)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Reports und Potential Dock-Absturz beim ersten \u00d6ffnen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>setFloating(True)<\/code> im <code>visibilityChanged<\/code>-Handler loeste re-entranten Signal-Aufruf aus \u2192 Absturz<\/li>\n\n\n\n<li>Fix: Signal sofort trennen + Initialisierung per <code>QTimer.singleShot(0, ...)<\/code> zurueckstellen<\/li>\n\n\n\n<li>Betrifft <code>_on_reports_visibility<\/code> und <code>_on_potential_visibility<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Genre \/ Tags (BL-063)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Songs koennen mehrere Genres\/Tags erhalten (Many-to-Many)<\/li>\n\n\n\n<li><strong>65 Default-Genres<\/strong> aus Square Dance Labels + musicforcallers.com (Dekaden, Stile, Kuenstler, Themen, <a href=\"https:\/\/callerscaddy.de\/new-music-for-callers-how-to-find-them\/\">Square Dance spezifisch<\/a>, NEW)<\/li>\n\n\n\n<li><code>seed_default_genres()<\/code> ist idempotent \u2014 fuegt nur fehlende Genres ein, bestehende bleiben erhalten<\/li>\n\n\n\n<li><strong>Genre-Verwaltung<\/strong> (Menue Datenbank \u2192 &#8222;Genres verwalten\u2026&#8220;):<\/li>\n\n\n\n<li>Liste aller Genres mit Song-Zaehler<\/li>\n\n\n\n<li>Anlegen, Umbenennen, Loeschen<\/li>\n\n\n\n<li>Beim Loeschen mit zugeordneten Songs: Wahlmoeglichkeit &#8222;Auf anderes Genre umbiegen&#8220; oder &#8222;Einfach entfernen&#8220;<\/li>\n\n\n\n<li><strong>Song-Datensatz<\/strong>: Genre-Tags als klickbare Anzeige + &#8222;\u2026&#8220;-Button oeffnet Checkbox-Dialog<\/li>\n\n\n\n<li>Neues Genre direkt im Dialog anlegen moeglich<\/li>\n\n\n\n<li>Aenderungen werden sofort gespeichert<\/li>\n\n\n\n<li><strong>Import-Keyword-Matching<\/strong>: Beim Import werden Genres automatisch aus dem Dateinamen vorgeschlagen (z.B. &#8222;Christmas&#8220; aus &#8222;Xmas Song.mp3&#8220;)<\/li>\n\n\n\n<li><strong>Rules-Aktionen<\/strong>: &#8222;Add Genre to Song&#8220; und &#8222;Remove Genre from Song&#8220;<\/li>\n\n\n\n<li>Parameter als Dropdown aller vorhandenen Genres (kein Freitext \u2192 keine Duplikate)<\/li>\n\n\n\n<li>Neuer <code>genre_choice<\/code>-Parametertyp in rule_widget.py mit <code>genre_names_provider<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rules: Aktionen per Drag&amp;Drop umordnen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Jede Aktion-Zeile hat links ein <strong>\u2261<\/strong>-Handle (Cursor \u2195)<\/li>\n\n\n\n<li>Ziehen verschiebt die Zeile live an die neue Position<\/li>\n\n\n\n<li>Reihenfolge der Aktionen ist sofort gespeichert<\/li>\n\n\n\n<li>Bugfix: <code>_on_action_type_changed<\/code> hatte falschen Index nach Handle-Einfuegung (combo wurde statt Params entfernt)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.44 \u2014 Multi-Musikpfade, Import Kopieren\/Belassen (2026-04-05)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Mehrere Musik-Verzeichnisse (bis zu 4)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bis zu 4 Musikpfade konfigurierbar (Slot 1 = Hauptordner, Slots 2\u20134 optional)<\/li>\n\n\n\n<li><code>find_song_file()<\/code> sucht in Reihenfolge Slot 1 \u2192 2 \u2192 3 \u2192 4, gibt ersten Treffer zurueck<\/li>\n\n\n\n<li>Neuer Dialog &#8222;Musikpfade verwalten&#8220; (Menue Pfade) mit Browse + Leeren pro Slot<\/li>\n\n\n\n<li>Menuetext: &#8222;Musik-Verzeichnis aendern&#8220; \u2192 &#8222;Musikpfade verwalten&#8220;<\/li>\n\n\n\n<li>Migration: Alter INI-Key <code>paths\/music_dir<\/code> wird automatisch nach <code>paths\/music_dir_1<\/code> uebertragen<\/li>\n\n\n\n<li>Gut fuer Caller mit Programmdaten auf einem und Musikdateien auf einem anderen Laufwerk<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Import: Kopieren oder am Ort belassen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Zwischendialog nach Songtyp-Auswahl: &#8222;Dateien kopieren?&#8220; oder &#8222;Am Ort belassen&#8220;<\/li>\n\n\n\n<li>Kopieren: bisheriges Verhalten \u2014 Dateien gehen ins music\/-Hauptverzeichnis<\/li>\n\n\n\n<li>Belassen: Dateien bleiben wo sie sind, nur DB-Eintrag wird angelegt<\/li>\n\n\n\n<li>Bei Belassen: wenn Quellordner noch nicht als Musikpfad eingetragen, Nachfrage ob er als freier Slot ergaenzt werden soll<\/li>\n\n\n\n<li>Wenn alle 4 Slots belegt: Hinweismeldung mit Verweis auf den Verwaltungs-Dialog<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Single-Instance-Lock robuster (Race Condition bei Doppelklick)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ersetzt QLocalServer\/QLocalSocket durch atomaren QLockFile<\/li>\n\n\n\n<li>Doppelklick auf run_test.bat oder EXE startet keine zweite Instanz mehr<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Mindestbreite Player- und Loop-Dock<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Player-Dock: min. 340px \u2014 verhindert unleshares Zusammenquetschen<\/li>\n\n\n\n<li>Loop-Dock: min. 400px \u2014 alle 4 Buttons bleiben nebeneinander lesbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance-Optimierung Startup (\u221222% auf Laptop)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reports-Dock: <code>setFloating(True)<\/code> wird nicht mehr beim Start gesetzt, sondern erst beim ersten Oeffnen (lazy) \u2192 \u2212318ms auf Laptop<\/li>\n\n\n\n<li>Potential-Dock: gleiche Optimierung \u2192 \u2212137ms auf Laptop<\/li>\n\n\n\n<li>Gesamtersparnis Laptop: ~526ms (2415ms \u2192 1889ms)<\/li>\n\n\n\n<li><strong>Hinweis fuer Kunden<\/strong>: Beim ersten Start nach einem Update kann die App einige Sekunden laenger brauchen \u2014 Windows Defender scannt die neuen Dateien. Ab dem zweiten Start ist alles normal.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.43 \u2014 UI-Mindesthoehen, Song-Data-Scroll, Erststart-Sprachabfrage, Quickwin-Bundle (2026-04-04)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Rule-Aktion: Song-Tempo aendern (persistent)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>song_tempo_change<\/code> ergaenzt zur bisherigen <code>tempo_change<\/code><\/li>\n\n\n\n<li><strong>tempo_change<\/strong> (umbenannt zu &#8222;Change Today&#8217;s Tempo (\u00b1%)&#8220;): heutiges Tempo, nicht persistent<\/li>\n\n\n\n<li><strong>song_tempo_change<\/strong> (&#8222;Change Song Tempo (\u00b1%, persistent)&#8220;): aendert das Song-Tempo und speichert den Wert ueber die bestehende Auto-Save-Kette am Song in der Datenbank<\/li>\n\n\n\n<li>Parameter: <code>delta<\/code> als Integer-Prozent, Clamp 50-150%<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Import\/Migration fehlertolerant (BL-065)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Manueller Import: Pro-Datei-try\/except \u2014 defekte\/unlesbare Dateien werden uebersprungen, Session laeuft weiter<\/li>\n\n\n\n<li>CC1-Migration: <code>shutil.copy2<\/code> pro MP3 gekapselt, Fehler protokolliert, Report am Ende<\/li>\n\n\n\n<li>SqView-Migration: gleiche Fehlerresilienz<\/li>\n\n\n\n<li>Auch <code>player._load_file()<\/code> am Ende des Imports fehlertolerant \u2014 eine defekte letzte Datei bricht die Summary nicht mehr ab<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Ordner-Import mit Unterordnern (BL-032)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Zwischendialog &#8222;Importquelle&#8220;: Einzelne Dateien oder Ordner (inkl. Unterordner)<\/li>\n\n\n\n<li>Bei Ordner-Auswahl wird rekursiv nach .mp3\/.wav\/.flac\/.ogg\/.aiff\/.aif gesucht<\/li>\n\n\n\n<li>Thorstens Langzeit-Feature-Request erfuellt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Aktiver Tab besser erkennbar (BL-060)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>QTabBar::tab:selected<\/code> in allen Themes mit <code>font-weight: bold<\/code><\/li>\n\n\n\n<li>Win11: Border von 2px auf 3px, expliziter <code>widget_bg<\/code>-Hintergrund<\/li>\n\n\n\n<li>Default: zusaetzliche 2px Top-Border in Selection-Farbe<\/li>\n\n\n\n<li>Light: Bold ergaenzt, elegant war bereits bold<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Import-Hinweis: wo die Songs landen (BL-062)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nach erfolgreichem Import wird das Song-List-Dock automatisch in den Vordergrund geholt<\/li>\n\n\n\n<li>Import-Zusammenfassung enthaelt neuen Hinweis: &#8222;Die neuen Songs wurden der Songliste hinzugefuegt.&#8220;<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">TIC-0014: Player-Mindesthoehe beim App-Resize<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>MainWindow.setMinimumSize()<\/code> von (1100, 650) auf (1100, 720) erhoeht<\/li>\n\n\n\n<li>Summe aus Player (350) + Loop (240) + Titelleisten + Menu + Statusbar passt jetzt in die Mindesthoehe<\/li>\n\n\n\n<li>Untere Button-Zeile (Lokation, Planner, Lyrics) wird beim Verkleinern des Hauptfensters nicht mehr abgeschnitten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Erststart-Sprachabfrage (BL-058)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim allerersten Start (keine Sprache in INI) erscheint ein Dialog: &#8222;Start in English&#8220; \/ &#8222;In Deutsch starten&#8220;<\/li>\n\n\n\n<li>Sprache wird danach in der INI gespeichert, Dialog erscheint nur einmal<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">UI: Mindesthoehen gegen Quetschen (TIC-0008, TIC-0013)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Player-Buttons (Play, Pause, Stop, Fade Out, Lokation, Planner, Lyrics): Mindesthoehe 34px<\/li>\n\n\n\n<li>Player-SpinBoxen (Tempo, Pitch): Mindesthoehe 24px mit Labels 16px<\/li>\n\n\n\n<li>Player-Widget gesamt: Mindesthoehe 350px, wird nach Layout-Restore erneut erzwungen<\/li>\n\n\n\n<li>Loop-Widget (&#8222;New Songs&#8220;): Mindesthoehe 240px, Buttons 52px, festes Spacing 6px<\/li>\n\n\n\n<li>Verhindert unleserliche UI auf kleinen Bildschirmen oder bei hoher DPI-Skalierung (z.B. 1.8x)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Song Data: ScrollArea (TIC-0012)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Song-Data-Widget hat jetzt eine vertikale Scrollleiste statt Quetschen bei kleinem Dock<\/li>\n\n\n\n<li>Alle Felder bleiben lesbar unabhaengig von der Widget-Hoehe<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: &#8222;Titel&#8220;-Spalte nicht uebersetzt (TIC-0009)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Spalte &#8222;Titel&#8220; in Playlist und Planner wird jetzt korrekt ueber das Uebersetzungssystem ausgegeben (&#8222;Title&#8220; auf Englisch)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix: Show\/Hide-Buttons sind jetzt echtes Toggle (TIC-0010, TIC-0011)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>_toggle_dock()<\/code> war bisher nur Show + raise \u2014 zweiter Klick blendete nicht aus<\/li>\n\n\n\n<li>Planner- und Lyrics-Button blenden das jeweilige Dock jetzt beim zweiten Klick wieder aus<\/li>\n\n\n\n<li>Sonderfall hinterer Tab im Stapel: Dock wird nur nach vorne geholt, nicht versteckt<\/li>\n\n\n\n<li>Sortier-Preselect im Planner laeuft nur noch beim Oeffnen, nicht beim Schliessen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.42 \u2014 Rules-Erweiterungen, Planner-Loeschen, App-Menu &amp; Song-Anzeige ohne Datei (2026-03-28)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Rule-Aktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Go To Position<\/strong> (BL-044): Springt zu Start, Loop-In, Loop-Out oder Ende des Songs. Position ueber Dropdown waehlbar, nutzt Crossfade-Parameter fuer sanften Uebergang<\/li>\n\n\n\n<li><strong>Toggle Loop Active<\/strong> (BL-045): Schaltet die Loop-Checkbox an\/aus \u2014 per Tastenkuerzel oder Regel steuerbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Planner: Playlist komplett loeschen (BL-049)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer roter \u2716-Button ueber dem Bestaetigungs-Button im Planner<\/li>\n\n\n\n<li>Loescht die gesamte Playlist nach Rueckfrage-Dialog<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Song-Daten ohne Audiodatei (BL-051)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Song-Daten und Lyrics werden jetzt auch angezeigt, wenn keine MP3\/Audio-Datei vorhanden ist<\/li>\n\n\n\n<li>Dateiname-Feld wird rot hinterlegt als visueller Hinweis<\/li>\n\n\n\n<li>Warnung nur noch in der Statusbar (kein blockierendes Popup mehr)<\/li>\n\n\n\n<li>Ermoeglicht manuelles Verlinken einer Datei oder Einsicht in Migrationsdaten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">App-Menu (BL-052)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer erster Menueeintrag &#8222;App&#8220; mit &#8222;Beenden&#8220; \u2014 sauberes Schliessen ueber das Menu statt nur ueber das X<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rules-Widget<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Parametertyp &#8222;choice&#8220; fuer Dropdown-Auswahl in Rule-Aktionen (z.B. GoTo-Position)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.41 \u2014 Song-Verwaltung, Foto-Widget, RTF-Bereinigung &amp; MDB-Erweiterungstabellen (2026-03-27)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Song loeschen (BL-039)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Songs koennen einzeln aus der Datenbank geloescht werden<\/li>\n\n\n\n<li>Sicherheitsabfrage mit Option, Historiendaten (play_history, song_location_stats) mitzuloeschen<\/li>\n\n\n\n<li>Auch per Entf-Taste in der Songliste aufrufbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Multi-File-Import mit Typ-Auswahl<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beim Importieren neuer Songs wird vorher der Songtyp abgefragt (Pattern \/ Singing \/ Beides)<\/li>\n\n\n\n<li>Mehrere Dateien gleichzeitig auswaehlbar (Multi-File-Dialog)<\/li>\n\n\n\n<li>Gewaehlter Typ wird auf alle importierten Songs angewendet<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Foto-Widget (BL-041)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Dock-Widget mit Kamera-Vorschau (QtMultimedia: QCamera + QMediaCaptureSession)<\/li>\n\n\n\n<li>RAM-only: Fotos werden nur im Speicher gehalten, kein Dateisystem, keine DB<\/li>\n\n\n\n<li>Lazy-Init: Kamera wird erst bei erster Sichtbarkeit des Docks initialisiert<\/li>\n\n\n\n<li>QStackedWidget fuer Umschaltung zwischen Kamera-Preview und aufgenommenem Foto<\/li>\n\n\n\n<li>Rules-Aktionen: photo_capture (Kamera starten + Timer) und photo_show (90% Screen)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">RTF-Bereinigung (BL-043)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lyrics-Import: Word-Muell aus RTF-Dateien wird automatisch entfernt (datastore, themedata, colorschememapping, xmlnstbl, latentstyles etc.)<\/li>\n\n\n\n<li>Whitelist-Ansatz: Nur bekannte RTF-Gruppen (fonttbl, colortbl, stylesheet) werden behalten<\/li>\n\n\n\n<li>Bei betroffenen Dateien bis zu 48% Dateigroesse eingespart<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">MDB-Migration: Erweiterte Tabellen (BL-047)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>access-parser Monkey-Patches fuer erweiterte CC1-Tabellen (Off-by-One, Row-Count, Primary-Key)<\/li>\n\n\n\n<li>History-Based Reconstruction: Wenn normale Song-Felder unlesbar, werden Songs aus der Historie rekonstruiert<\/li>\n\n\n\n<li>Case-insensitiver Fallback fuer Tabellen- und Spaltennamen (access-parser liefert inkonsistente Gross-\/Kleinschreibung)<\/li>\n\n\n\n<li>Windows-Console: Unicode-sichere Log-Ausgaben (ASCII statt Sonderzeichen)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SqView-Migration bereit fuer groessere Testdaten<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.40 \u2014 Loop-Anzahl, Performance-Optimierung &amp; Mehrfachstart-Schutz (2026-03-26)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Loop-Anzahl \/ Zeitgesteuerter Loop (BL-042)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Funktion: Caller legt gewuenschte Pattern-Dauer fest, Callers Caddy berechnet die noetige Anzahl Loops<\/li>\n\n\n\n<li>Zwei Optionen (ein Loop mehr \/ ein Loop weniger) mit resultierender Gesamtdauer<\/li>\n\n\n\n<li>Loop-Anzahl wird im Player angezeigt (Loop X\/N bzw. Loop unendlich)<\/li>\n\n\n\n<li>Singing Calls zeigen &#8222;1&#8220; statt Unendlich-Zeichen in der Loops-Spalte<\/li>\n\n\n\n<li>Loop-Anzahl pro Playlist-Eintrag (nicht pro Song), persistiert in Playlist-Dateien<\/li>\n\n\n\n<li>Rueckwaertskompatibles Playlist-Format: Erkennt altes und neues Format automatisch<\/li>\n\n\n\n<li>Doppelklick auf Loops-Spalte oeffnet Loop-Anzahl-Dialog (Playlist + Planner)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Player-Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Song-Titel in eigener Zeile (16px fett), Info-Zeile darunter mit Timer + Loop-Count + BPM<\/li>\n\n\n\n<li>Loop-Marken (Loop-In \/ Loop-Out) werden als vertikale Linien auf dem Position-Slider angezeigt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Playlist + Planner<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Spalte &#8222;Dauer&#8220; mit berechneter Laufzeit pro Song (beruecksichtigt Loop-Anzahl)<\/li>\n\n\n\n<li>Gesamtdauer-Summe unter der Playlist \u2014 Caller kann den ganzen Abend verplanen<\/li>\n\n\n\n<li>Planner: Linker und rechter Bereich per QSplitter in der Groesse verschiebbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance-Optimierung (Startup \u221255%)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>App-Start: 1724ms \u2192 780ms durch Lazy-Init von Reports, Potential und Planner<\/li>\n\n\n\n<li>Songliste: set_last_played_map aktualisiert nur noch Datumsspalte statt Table-Rebuild<\/li>\n\n\n\n<li>Playlist-Dauer: Negative Cache + Inline-Summe (250 Songs: 367ms \u2192 5ms)<\/li>\n\n\n\n<li>Performance-Logging-System: <code>perf_start()<\/code> \/ <code>perf_log()<\/code> \/ <code>perf_split()<\/code><\/li>\n\n\n\n<li>Aktivierbar via INI-Schalter <code>debug\/performance_logging = true<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Mehrfachstart-Schutz<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Doppelter App-Start wird verhindert (QLocalServer\/QLocalSocket)<\/li>\n\n\n\n<li>Fehlermeldung wenn Callers Caddy bereits laeuft<\/li>\n\n\n\n<li>Wait-Cursor (Sanduhr) waehrend des App-Starts<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Uebersetzungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Schluessel: header_duration, playlist_total, loop_count_per_loop, loop_count_before, loop_count_after, already_running<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.39 \u2014 SqView-Migration, Song-Volume &amp; Verbesserungen (2026-03-26)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">SqView-Migration (Beta)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Migrations-Pfad: SqView \u2192 Callers Caddy 2.0<\/li>\n\n\n\n<li>Liest sqview.db: Songs (Tempo, Pitch, Volume, Loops), Abspielhistorie, Lyrics-Zuordnungen<\/li>\n\n\n\n<li>Auto-Detect: Musik- und Lyrics-Ordner werden aus SqView-INI erkannt<\/li>\n\n\n\n<li>Ausfuehrliches Log pro Song: MP3-Status, Lyrics, Loop-Punkte, Pitch, Volume<\/li>\n\n\n\n<li>Nacharbeit-Bericht am Ende: fehlende MP3s und Lyrics aufgelistet<\/li>\n\n\n\n<li>Beta-Warnung: &#8222;Noch im Test-Stadium. Benutzung auf eigene Gefahr!&#8220;<\/li>\n\n\n\n<li>Dateiname-Parsing: &#8222;Title-Label.mp3&#8220; wird automatisch in Titel + Label zerlegt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Song-Volume<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Volume-Feld in Song-Daten wird jetzt auf die Audio-Engine angewandt (multiplikativ)<\/li>\n\n\n\n<li>Smooth-Rampe bei Volume-Aenderung (~50ms), kein Knistern oder Knacksen<\/li>\n\n\n\n<li>Debounced DB-Save: nur Volume-Spalte, kein Lyrics-Reload bei Aenderung<\/li>\n\n\n\n<li>Range begrenzt auf 0.0\u20131.0 (0%\u2013100%)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Rules-Aktionen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Aktion: &#8222;Change Pitch&#8220; (\u00b1Halbtoene, konfigurierbare Schrittweite)<\/li>\n\n\n\n<li>Neue Aktion: &#8222;Change Volume&#8220; (\u00b1Faktor, konfigurierbare Schrittweite)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tutorial-Menu<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neuer Menuepunkt &#8222;Alle Tutorials beenden&#8220; (Gegenstueck zu &#8222;Alle zuruecksetzen&#8220;)<\/li>\n\n\n\n<li>Beendet laufendes Tutorial und markiert alle als abgeschlossen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Potential-Widget<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>FlowLayout fuer Check-Buttons: Buttons haben volle Textbreite, umbrechen automatisch bei schmalem Dock<\/li>\n\n\n\n<li>Doppelklick auf &#8222;Leere Lokation&#8220; oeffnet Lokation-Dialog mit der betroffenen Lokation vorselektiert<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfix<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tasten P und L funktionieren jetzt in Songliste\/Playlist fuer Type-to-Search<br>(wurden vorher vom app-weiten EventFilter geschluckt, auch bei deaktivierten Regeln)<\/li>\n\n\n\n<li>Tempo\/Pitch-Aenderung verursacht kein Audio-Knistern mehr (Debounced Save ohne Lyrics-Reload)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.38 \u2014 Lyrics-Redesign, Tutorials &amp; Bugfixes (2026-03-25)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Lyrics-Widget: As-Is-Rendering (Architektur-Vereinfachung)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lyrics werden jetzt 1:1 original dargestellt \u2014 wie im Browser oder Word<\/li>\n\n\n\n<li>Weisser Hintergrund, unabhaengig vom gewaehlten Theme<\/li>\n\n\n\n<li>Alle Farben (Textfarbe, Hintergrundfarbe, Highlights) bleiben original erhalten<\/li>\n\n\n\n<li>Sanitizer radikal vereinfacht: nur noch CSS-Link-Aufloesung + font-size-Entfernung<\/li>\n\n\n\n<li>Externe CSS-Dateien (z.B. cuesheet2.css) werden automatisch inlined<\/li>\n\n\n\n<li>RTF-Konverter: Unterstuetzung fuer \\highlight (Hintergrundfarben)<\/li>\n\n\n\n<li>RTF-Konverter: Korrekte Behandlung von *\\background und weiteren Header-Gruppen<\/li>\n\n\n\n<li>Neuer Button &#8222;Auto-Breite&#8220;: Skaliert Schrift so, dass Text in die Fensterbreite passt<\/li>\n\n\n\n<li>Auto-Breite auch als Rules-Aktion verfuegbar (&#8222;Lyrics Auto-Width&#8220;)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tutorials<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Tutorial: Loop Finder (6 Schritte: Wellenform, Suchbereich, Suchfenster, Analyse, Ergebnisse, Uebernehmen)<\/li>\n\n\n\n<li>Neues Tutorial: Rules (7 Schritte: Regelliste, Neue Regel, Name\/Aktiv\/Once, Trigger, Bedingungen, Aktionen, Import\/Export)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Song-Restart<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Play-Button bei laufendem Song = Neustart von vorne (seek 0)<\/li>\n\n\n\n<li>Kein Stop+Start mehr noetig, auch per F5-Rule nutzbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>HTML-Lyrics mit externem CSS werden jetzt korrekt dargestellt (TIC-0001)<\/li>\n\n\n\n<li>RTF-Lyrics mit Farben und Highlights werden originalgetreu angezeigt (TIC-0002)<\/li>\n\n\n\n<li>App-Icon in Titelleiste und Windows-Taskleiste (TIC-0004)<\/li>\n\n\n\n<li>CP1252-Encoding-Fallback beim Laden von Playlists (utf-8 Fehler)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Ticket-System<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Ticket-System unter 5_Tickets\/ fuer Fehlermeldungen und Fragen<\/li>\n\n\n\n<li>TICKETS.md als Uebersicht, ein Ordner pro Ticket mit Anhaengen<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.37 \u2014 Regel-Engine &amp; Automatisierung (2026-03-24)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Regel-Engine (neues System)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Komplett neues Automatisierungssystem: Trigger \u2192 Bedingungen \u2192 Aktionen<\/li>\n\n\n\n<li><strong>26 Trigger<\/strong>: App-Lifecycle (Start, Song gestartet\/pausiert\/gestoppt\/resumed\/gewechselt), periodischer Timer, Tastatur (F1\u2013F12, Space, L, P), Manager geschlossen<\/li>\n\n\n\n<li><strong>9 Bedingungen<\/strong>: Songtyp (Singing\/Patter), Lyrics vorhanden\/nicht, Loop gesetzt\/nicht, Location gewaehlt\/nicht, Spielzeit ueber Schwellwert<\/li>\n\n\n\n<li><strong>25 Aktionen<\/strong>: Dock oeffnen\/schliessen\/Vollbild\/Fokus, Layout laden, Play\/Pause\/Stop\/Fade-Out\/Toggle, Auto-Advance, Auto-Scroll Start\/Stop, Tempo aendern, Statusbar-Nachricht, Log-Nachricht, System-Ping, Warn-Hintergrund (Ampel), Location-Dialog, Manager-Toggle, Auto-Loop-Finder<\/li>\n\n\n\n<li>Bedingungslogik: Flexible UND\/ODER-Gruppen (z.B. \u201eSinging UND Lyrics vorhanden ODER Patter UND Loop gesetzt&#8220;)<\/li>\n\n\n\n<li>\u201eEinmal pro Song&#8220;-Option: Regel feuert maximal einmal pro Song<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Regel-Editor (neues Widget)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dockbares Editor-Widget mit zweigeteiltem Layout (Regelliste links, Editor rechts)<\/li>\n\n\n\n<li>Suchfeld zum Filtern nach Name oder Trigger<\/li>\n\n\n\n<li>Sortierbare Tabelle: Aktiv-Checkbox, Name, Trigger, Quelle (System\/User)<\/li>\n\n\n\n<li>Dynamische Parameter-Eingabefelder je nach Aktions-\/Bedingungstyp<\/li>\n\n\n\n<li>Buttons: Hinzufuegen, Duplizieren, Loeschen, Hoch\/Runter, Export, Import<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">System- vs. User-Regeln<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>13 vorinstallierte System-Regeln<\/strong> (nur Aktiv-Toggle aenderbar, nicht editierbar):<\/li>\n\n\n\n<li>Singing Call \u2192 Lyrics Vollbild mit Auto-Scroll (Start + Resume)<\/li>\n\n\n\n<li>Singing Call Stop\/Pause \u2192 Default Layout zurueck<\/li>\n\n\n\n<li>Song Stop \u2192 Auto-Advance<\/li>\n\n\n\n<li>Manager geschlossen \u2192 Playlist fokussieren<\/li>\n\n\n\n<li>Tastatur-Shortcuts: F5=Play, F6=Pause, F7=Stop, F8=Fade-Out, Space=Play\/Pause, L=Location, P=Manager<\/li>\n\n\n\n<li><strong>User-Regeln<\/strong>: Voll editierbar, Import\/Export als JSON, frei sortierbar<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Regel-Logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eigene Log-Datei <code>rules\/rules.log<\/code> mit Kategorien: TRIGGER, MATCH, NO_MATCH, ACTION, ERROR, BLOCKED<\/li>\n\n\n\n<li>Automatische Rotation bei 1 MB (beh\u00e4lt 500 Zeilen)<\/li>\n\n\n\n<li>Hilft bei Diagnose, warum Regeln feuern oder nicht<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Auto-Loop-Finder (Regel-Aktion)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neue Aktion <code>auto_set_best_loop<\/code>: Analysiert den Song automatisch und setzt den besten 64-Beat-Loop<\/li>\n\n\n\n<li>Bevorzugt 64-Beat-Loops, Fallback auf hoechsten Score<\/li>\n\n\n\n<li>&#8222;Bitte warten&#8220;-Overlay waehrend der Analyse (halbtransparent, verschwindet automatisch)<\/li>\n\n\n\n<li>Kann per Regel z.B. bei Song-Start automatisch ausgeloest werden<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance-Optimierung<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Lazy Waveform<\/strong>: Loop-Finder-Waveform wird erst bei Sichtbarkeit geladen (spart ~100-400ms beim Songwechsel)<\/li>\n\n\n\n<li><strong>Gezieltes Song-Update<\/strong>: Nach Abspielen wird nur die Last-Played-Spalte aktualisiert statt die gesamte Songliste neu aufgebaut (~4-22ms statt ~400-1200ms)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Loop-Widget: Neues Button-Layout<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Alle 4 Buttons (Set In, Clear, Set Out, Test Loop) in einer flachen Zeile<\/li>\n\n\n\n<li>Buttons schrumpfen bei Platzmangel mit automatischem Textumbruch<\/li>\n\n\n\n<li>Player-Spalte laesst sich jetzt deutlich schmaler ziehen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Dock-Widget-Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Features-Persistenz<\/strong>: Dock-Faehigkeiten (Verschieben\/Andocken\/Schliessen) bleiben nach Layout-Wiederherstellung erhalten (Qt-Bug behoben)<\/li>\n\n\n\n<li><strong>Kleinere Fenstergroessen<\/strong>: Docks lassen sich jetzt auch andocken, wenn die App nicht im Vollbild laeuft (minimumSize-Fix)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Loop-Guard<\/strong>: Snapshot-Werte von 0.0 werden korrekt als ungueltig erkannt \u2014 verhindert Ueberschreiben guter Loop-Werte beim Schliessen<\/li>\n\n\n\n<li><strong>Audition\/Beat Snap<\/strong>: Abspielen im Loop Finder und Beat Snap wird nicht mehr in der Play-Historie geloggt<\/li>\n\n\n\n<li><strong>Loop Finder schliessen<\/strong>: Stoppt laufende Wiedergabe automatisch<\/li>\n\n\n\n<li><strong>Resume-Regel<\/strong>: Funktioniert wieder zuverlaessig nach Layout-Wechsel (Focus-Restore nach restoreState)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.36 \u2014 Loop Finder &amp; UI-Reorganisation (2026-03-21)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Loop Finder (neues Widget)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues dockbares Fenster &#8222;Loop Finder&#8220; \u2014 sucht automatisch passende Loop-Punkte<\/li>\n\n\n\n<li>Aehnlichkeitsbasierte Analyse: Vergleicht Phrasen im vorderen und hinteren Songbereich<\/li>\n\n\n\n<li>8-Beat-Nummerierung: Alle Beats werden 1-8 durchgezaehlt, Spruenge nur zwischen gleichen Beat-Positionen<\/li>\n\n\n\n<li>Downbeat-Erkennung: Bevorzugt Kandidaten auf geschaetztem Beat 1 (Kick-Energie-Heuristik)<\/li>\n\n\n\n<li>Chroma-basierter Harmonie-Score (FFT \u2192 12 Halbtoene, rein mit scipy\/numpy)<\/li>\n\n\n\n<li>Einstellbares Vergleichsfenster: 4, 8, 16, 32 oder 64 Beats per ComboBox<\/li>\n\n\n\n<li>Einstellbare Suchbereiche: 4 Prozentfelder (Default 7%\/21%\/64%\/79%) mit Reset-Button<\/li>\n\n\n\n<li>Waveform-Uebersicht mit farbigen Suchbereichen (gruen = Loop-In, orange = Loop-Out)<\/li>\n\n\n\n<li>4 verschiebbare Handles (beide Seiten pro Region per Maus anpassbar)<\/li>\n\n\n\n<li>7 Singing-Call-Segmente ueber der Waveform (Opener, 1-4, Middle Break, Closer)<\/li>\n\n\n\n<li>Weisse gestrichelte Marken zeigen den selektierten Vorschlag in der Waveform<\/li>\n\n\n\n<li>Sortierbare Ergebnistabelle: Klick auf Spaltenueberschrift sortiert nach Score, Beat, Zeit<\/li>\n\n\n\n<li>Audition-Funktion: Startet 5 Sekunden vor Loop-Out, springt, stoppt 2 Sekunden nach Loop-In<\/li>\n\n\n\n<li>Budget-basierter Loop-Mechanismus: Callback zaehlt Output-Samples, kein Stretcher-Zugriff aus UI-Threadchlag als Loop-In\/Loop-Out in den Player<\/li>\n\n\n\n<li>Analyse laeuft in QThread (nicht blockierend)<\/li>\n\n\n\n<li>Keine neuen Abhaengigkeiten \u2014 alles mit scipy + numpy<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">UI-Reorganisation (Loop-Widget)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Loop Active \u2192 Player<\/strong>: Checkbox aus dem Loop-Widget in die Player-Toolbar verschoben (rechts neben Lyrics)<\/li>\n\n\n\n<li><strong>3-Spalten-Layout<\/strong>: Loop-In-Zeit und Loop-Out-Zeit stehen zentriert ueber ihren Buttons<\/li>\n\n\n\n<li><strong>Button-Reihe<\/strong>: Set Loop-In | Set Loop-Out | Test Loop nebeneinander<\/li>\n\n\n\n<li><strong>Neue Button-Reihe<\/strong>: Loop Finder | Beat Snap nebeneinander<\/li>\n\n\n\n<li>Fixe Zeilenhoehe im 3-Spalten-Grid (dehnt sich nicht bei groesserem Widget)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Loop Finder Dock<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eigenes Dock-Widget, darf nicht mit anderen Widgets andocken (Qt.NoDockWidgetArea)<\/li>\n\n\n\n<li>Oeffnet sich ueber den neuen &#8222;Loop Finder&#8220;-Button im Loop-Widget<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.35 \u2014 Guided Tutorials &amp; Verbesserter Loop-Guard (2026-03-20)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/callerscaddy.de\/tutorials\/\" data-type=\"post\" data-id=\"220\">Tutorial-System<\/a> (13 Tutorials)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues gef\u00fchrtes Tutorial-System mit Tooltip-Overlays und Highlight-Rahmen<\/li>\n\n\n\n<li>11 Widget-Tutorials: Player, Layout, Songliste, Song-Daten, Planner, Playlist, Loop, Lyrics, Sequenzen, Reports, Potential<\/li>\n\n\n\n<li>2 Dialog-Tutorials: Lokationen, Beat Snap<\/li>\n\n\n\n<li>Prioritaetsbasierte Reihenfolge: Player \u2192 Lokationen \u2192 Layout \u2192 Songliste \u2192 \u2026 \u2192 Potential<\/li>\n\n\n\n<li>Automatisches Chaining: Nach Abschluss eines Tutorials wird das naechste angeboten<\/li>\n\n\n\n<li>Tutorial-Angebot ablehnbar: &#8222;Nicht jetzt&#8220; pausiert Tutorials fuer die Sitzung<\/li>\n\n\n\n<li>Schritt-Navigation: Weiter, Zurueck, Ueberspringen + Schritt-Anzeige (z.B. &#8222;3 \/ 5&#8220;)<\/li>\n\n\n\n<li>Enter = Weiter, Escape = Ueberspringen<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tutorial-Menu<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Untermenu &#8222;Tutorials&#8220; mit allen Tutorials in Prioritaetsreihenfolge<\/li>\n\n\n\n<li>Haekchen (\u2713) vor bereits abgeschlossenen Tutorials<\/li>\n\n\n\n<li>&#8222;Alle Tutorials zuruecksetzen&#8220; setzt den Fortschritt komplett zurueck<\/li>\n\n\n\n<li>Menu-Auswahl hat Vorrang ueber automatisches &#8222;naechstes Tutorial&#8220;<\/li>\n\n\n\n<li>Einzelne Tutorials koennen jederzeit ueber das Menu neu gestartet werden<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tutorial-Architektur<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Drei-Komponenten-System: Transparentes Overlay (Klick-Faenger) + Highlight-Rahmen + Tooltip-Popup<\/li>\n\n\n\n<li>Highlight und Tooltip als eigenstaendige Tool-Fenster (liegen ueber QDockWidgets)<\/li>\n\n\n\n<li>Multi-Element-Highlighting: Mehrere Elemente gleichzeitig rahmen (z.B. BPM-Feld + Auto-Button)<\/li>\n\n\n\n<li>Dialog-Tutorials: Eigene leichtgewichtige Engine fuer modale Dialoge (LocationDialog, BeatSnapDialog)<\/li>\n\n\n\n<li>Spezial-Pfade: <code>_menu_bar<\/code>, <code>_dock_XXX_title<\/code> fuer Menu und Dock-Titelleisten<\/li>\n\n\n\n<li>Floating-Dock-Management: Lose Docks werden waehrend Tutorials versteckt und danach wiederhergestellt<\/li>\n\n\n\n<li>Tooltip-Box mit eigenem paintEvent (opaker Hintergrund trotz transparentem Overlay)<\/li>\n\n\n\n<li>Dedizierte Skin-Farben: <code>tutorial_box_bg<\/code>, <code>tutorial_box_text<\/code>, <code>tutorial_highlight<\/code> in allen 4 Themes<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Beat Snap: &#8222;Adjust&#8220; \u2192 &#8222;Snap&#8220;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Button-Beschriftung von &#8222;Adjust&#8220; zu &#8222;Snap&#8220; umbenannt (inklusive Tooltip und Status-Text)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Verbesserter Loop-Guard (Datenbank)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Erweiterter Schutz gegen versehentliches Ueberschreiben von Loop-Werten<\/li>\n\n\n\n<li>Neuer Guard 2: Erkennt das Engine-Reset-Muster (loop_in=0 + loop_out=Songdauer) und schuetzt gespeicherte Werte<\/li>\n\n\n\n<li>Bisheriger Guard schuetzte nur gegen 0.0, nicht gegen die Songdauer als loop_out<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Win11 Theme<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zoom-SVG-Icons: Strichfarbe von dunkel (#1b1b1b) auf weiss (#ffffff) geaendert (bessere Sichtbarkeit auf blauem Hintergrund)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.34 \u2014 Keyboard-Shortcuts &amp; Elegant Gold Theme (2026-03-19)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Keyboard-Shortcuts (App-weit)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>L-Taste<\/strong>: Oeffnet Lokations-Auswahl-Dialog (mit Fokus auf Lokationsliste)<\/li>\n\n\n\n<li><strong>P-Taste<\/strong>: Oeffnet\/schliesst Planner (mit Fokus auf Pool-Tabelle)<\/li>\n\n\n\n<li>App-weiter EventFilter statt QShortcut (funktioniert auch bei fokussierten Tabellen\/Listen)<\/li>\n\n\n\n<li>Modale Dialoge blockieren Shortcuts automatisch<\/li>\n\n\n\n<li>Textfelder\/SpinBoxen werden erkannt und nicht abgefangen<\/li>\n\n\n\n<li>Planner-Sortierung wird automatisch vorausgewaehlt (Empfehlung bei Lokation, Qualitaet sonst)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Elegant Gold Theme<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues Theme &#8222;Elegant Gold&#8220;: Anthrazit-Basis mit strahlendem Gold (#d4a017)<\/li>\n\n\n\n<li>Goldene Titelleisten, Buttons, aktive Tabs, Header-Trennlinien und Tooltips<\/li>\n\n\n\n<li>Deaktivierte Elemente in mittlerem Goldton (#7a6a2e)<\/li>\n\n\n\n<li>Eingabefelder und Listenbereiche mit leichtem Goldfarbton (#2e2a1f)<\/li>\n\n\n\n<li>SVG-Icons: Pfeile und Dock-Buttons schwarz (#000000), Lupen\/Zahnrad dunkelbraun (#2a2518)<\/li>\n\n\n\n<li>Section-Bar-Segmente (Singing Call 1\/2\/3\/5) in mittlerem Goldton<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Fokus-Management<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Startup-Fokus auf Songliste (verhindert Shortcut-Blockade durch SpinBox)<\/li>\n\n\n\n<li>Floating-Dock-Aktivierung: <code>activateWindow()<\/code> vor <code>setFocus()<\/code> fuer Keyboard-Input<\/li>\n\n\n\n<li>Lokations-Dialog: Fokus auf Liste bei vorhandenen Eintraegen, auf Hinzufuegen-Button bei leerer Liste<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tooltip-Verbesserungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lokations- und Planner-Buttons zeigen Shortcut-Hinweis im Tooltip (L) \/ (P)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.33 \u2014 Potential-Widget &amp; Menu-Umbau (2026-03-18)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/callerscaddy.de\/clean-up-your-song-database\/\" target=\"_blank\" data-type=\"post\" data-id=\"183\" rel=\"noreferrer noopener\">Potential-Widget (Datenqualitaet)<\/a><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues dockbares Fenster &#8222;Potential&#8220; \u2014 zeigt Optimierungspotential in der Songdatenbank<\/li>\n\n\n\n<li>5 Checks mit Badge-Counter auf den Buttons:<\/li>\n\n\n\n<li>Singing Calls ohne Lyrics<\/li>\n\n\n\n<li>Pattern ohne Loop-Marken<\/li>\n\n\n\n<li>Loops ohne BeatSnap-Optimierung<\/li>\n\n\n\n<li>Lokationen ohne Abspielhistorie<\/li>\n\n\n\n<li>Verwaiste Historieneintraege (geloeschte Lokationen)<\/li>\n\n\n\n<li>Doppelklick navigiert zum betroffenen Objekt (Song-Daten, Beat Snap, Lokation)<\/li>\n\n\n\n<li>&#8222;Ignorieren&#8220;-Button: Einzelne Eintraege als bewusst akzeptiert markieren<\/li>\n\n\n\n<li>&#8222;Alle bereinigen&#8220;: Verwaiste History-Eintraege per Batch loeschen<\/li>\n\n\n\n<li>Lazy Loading: Daten werden erst beim Einblenden geladen<\/li>\n\n\n\n<li>DB: Neue Tabelle <code>potential_ignored<\/code> (check_type + entity_id)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Lokation loeschen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Loesch-Funktion funktioniert jetzt korrekt (vorher durch Foreign Key blockiert)<\/li>\n\n\n\n<li>Checkbox &#8222;Historiendaten ebenfalls loeschen&#8220; im Bestaetigungsdialog<\/li>\n\n\n\n<li>Ohne Checkbox: Historie bleibt als verwaiste Eintraege erhalten (im Potential sichtbar)<\/li>\n\n\n\n<li>Mit Checkbox: Historie und Stats werden komplett geloescht<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Menu-Umbau<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>&#8222;Design&#8220; umbenannt zu &#8222;Einstellungen&#8220; \/ &#8222;Settings&#8220;<\/li>\n\n\n\n<li>Datumsformat-Einstellung von Ansicht nach Einstellungen verschoben<\/li>\n\n\n\n<li>Sprach-Einstellung von Info nach Einstellungen verschoben<\/li>\n\n\n\n<li>&#8222;Skin&#8220; umbenannt zu &#8222;Theme&#8220; (Menue, Dialoge)<\/li>\n\n\n\n<li>Datumsformat-Label: &#8222;DE&#8220; geaendert zu &#8222;EU&#8220; (europaweit gueltig)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Default-Layout (3-spaltig)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues 3-Spalten-Layout als Standard bei Erstinstallation und Layout-Reset<\/li>\n\n\n\n<li>Spalte 1: Player oben, Loop\/Neu unten<\/li>\n\n\n\n<li>Spalte 2: Songliste und Playlist als Tabs (Songliste aktiv)<\/li>\n\n\n\n<li>Spalte 3: Lyrics, Song-Daten und Sequenzen als Tabs (Lyrics aktiv)<\/li>\n\n\n\n<li>Planner, Reports, Potential versteckt (ueber Menu oeffenbar)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technisch<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Layout-Version 3 (neues Dock erfordert Layout-Reset)<\/li>\n\n\n\n<li>Dock-Aufbau-Reihenfolge: Zuerst 3 Spalten horizontal, dann Spalte 1 vertikal teilen<br>(verhindert dass Player ueber volle Breite spannt)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.32 \u2014 Keyboard, Datei-Auswahl &amp; Loop-Verbesserungen (2026-03-18)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Keyboard &amp; Datei-Auswahl<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ENTER-Taste: Song in Songliste laden, Song im Planner-Pool zur Playlist hinzufuegen, Song in Playlist entfernen<\/li>\n\n\n\n<li>F-Tasten (F5-F8, Space) funktionieren jetzt auch bei abgedockten Fenstern (ApplicationShortcut)<\/li>\n\n\n\n<li>Datei-Auswahl-Button (&#8222;\u2026&#8220;) in Song-Daten: Audio-Datei nachtraeglich aendern<\/li>\n\n\n\n<li>Bei bereits vergebener Datei: Kopie-Dialog mit automatischer Kopie-Erstellung<\/li>\n\n\n\n<li>Erweiterte Audio-Format-Unterstuetzung: WAV, FLAC, OGG, AIFF neben MP3<\/li>\n\n\n\n<li>Audio-Format-Filter auch im Import-Dialog erweitert<\/li>\n\n\n\n<li>Neue DB-Methode <code>update_filename()<\/code> mit UNIQUE-Constraint-Pruefung<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/callerscaddy.de\/perfect-loops-with-mp3\/\" target=\"_blank\" data-type=\"post\" data-id=\"170\" rel=\"noreferrer noopener\">Loop-Crossfade<\/a><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nahtloser Loop-Uebergang durch Crossfade statt hartem Schnitt<\/li>\n\n\n\n<li>Crossfade-Dauer konfigurierbar via INI <code>loop\/crossfade_ms<\/code> (Default 46ms)<\/li>\n\n\n\n<li>Eliminiert WSOLA-Einschwing-Artefakte am Loop-Punkt (kein flush\/warmup noetig)<\/li>\n\n\n\n<li>Budget-basierter Loop-Mechanismus: Callback zaehlt Output-Samples, kein Stretcher-Zugriff aus UI-Thread<\/li>\n\n\n\n<li>Fallback-Sicherung: Feed-Level Loop-Back falls UI-Timer den Seek verpasst<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/callerscaddy.de\/perfect-loops-with-mp3\/\" target=\"_blank\" data-type=\"post\" data-id=\"170\" rel=\"noreferrer noopener\">Loop-Offset<\/a> (pro Song)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Automatische Offset-Messung via FFT-basierter Kreuzkorrelation (Tiefpass &lt;200Hz)<\/li>\n\n\n\n<li>Findet optimalen Versatz zwischen Loop-Ende und Loop-Anfang im Bass-Bereich<\/li>\n\n\n\n<li>Suchbereich \u00b12 Sekunden, waehlt den kleinsten Offset mit guter Korrelation (&gt;= 0.1)<\/li>\n\n\n\n<li>Offset wird pro Song in der DB gespeichert (<code>loop_offset_ms<\/code>)<\/li>\n\n\n\n<li>Manuelle Feinkorrektur ueber SpinBox in Song-Daten (\u00b13000ms, 0.5ms Schritte)<\/li>\n\n\n\n<li>Auto-Messung bei Beat Snap und Loop-Test, Ergebnis in DB + SpinBox<\/li>\n\n\n\n<li>DB-Migration: Neue Spalte <code>loop_offset_ms<\/code> wird automatisch angelegt<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bugfixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Playposition-Anzeige (Uhrzeit + Slider) klemmt nicht mehr bei Pattern-Start mit Loop<\/li>\n\n\n\n<li>Loop-Marken werden beim Dateiwechsel nicht mehr auf 0 zurueckgesetzt<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.31 \u2014 <a href=\"https:\/\/callerscaddy.de\/beat-snap-loop-adjust\/\" target=\"_blank\" data-type=\"post\" data-id=\"145\" rel=\"noreferrer noopener\">Beat Snap Audition<\/a> (2026-03-16)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beat Snap Dialog: Vorhoeren des Loop-Sprungs mit Waveform-Visualisierung<\/li>\n\n\n\n<li>Doppelte Waveform-Anzeige (Loop-Out oben, Loop-In unten) mit Cursor-Synchronisation<\/li>\n\n\n\n<li>Playback-Sample-Counter (<code>_playback_sample<\/code>) in Audio-Engine fuer praezise Positionsbestimmung<\/li>\n\n\n\n<li>Engine-Loop wird waehrend Audition deaktiviert (verhindert Doppel-Sprung durch Feed-Ahead)<\/li>\n\n\n\n<li>Layout-Versionierung: <code>_LAYOUT_VERSION<\/code> verhindert korrupte Dock-States bei Aenderungen<\/li>\n\n\n\n<li>Versioned <code>saveState()<\/code>\/<code>restoreState()<\/code> \u2014 alter State wird automatisch verworfen<\/li>\n\n\n\n<li>Bugfix: Dock-Widgets liessen sich nicht mehr einrasten nach P30\u2192P31 Dock-Aenderung<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.30 \u2014 BPM-Detection, Reports, Lyrics-Kontrast (2026-03-14)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auto-BPM-Erkennung via Comb-Filter-Bank (scipy\/numpy, keine neuen Pakete)<\/li>\n\n\n\n<li>Sub-Harmonik-Korrektur: Integer-Vielfache pruefen, hoehere Tempi bevorzugen<\/li>\n\n\n\n<li>BPM-Detection laeuft in QThread (nicht blockierend)<\/li>\n\n\n\n<li>Reports-Widget: Setlist\/Musikfolgeliste fuer GEMA mit TXT-Export<\/li>\n\n\n\n<li>Bidirektionale ComboBox-Filterung (Lokation \u2194 Datum)<\/li>\n\n\n\n<li><a href=\"https:\/\/callerscaddy.de\/farbwechsel-via-skins\/\" target=\"_blank\" data-type=\"post\" data-id=\"71\" rel=\"noreferrer noopener\">Lyrics-Kontrast: WCAG-basierte Farberkennung fuer Word-HTML (bgcolor, background, color)<\/a><\/li>\n\n\n\n<li>Sanitizer entfernt Block-Hintergruende, behaelt Inline-Highlights, ersetzt schlechte Textfarben<\/li>\n\n\n\n<li>Default-Stylesheet wird bei jedem Skin-Wechsel und setHtml() aktualisiert<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.29 \u2014 Release-Vorbereitung (2026-03-12)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Internationalisierung: i18n-Modul mit JSON-Translations (Deutsch\/Englisch)<\/li>\n\n\n\n<li>5-Stufen-Ordnerstruktur: 1_Source, 2_Test, 3_Build, 4_Release, _archive<\/li>\n\n\n\n<li>Build-Pipeline: PyInstaller-Spec + build.py (Vollpaket, Update, Source-ZIP)<\/li>\n\n\n\n<li>Clean-DB-Skript: Entfernt User-Daten, behaelt Referenzdaten (Sequenzen, <a href=\"https:\/\/callerscaddy.de\/tutorials\/\">Teaching Order<\/a>)<\/li>\n\n\n\n<li>Migration-EXE: Separater Access-Import-Prozess<\/li>\n\n\n\n<li>Portable Pfade: App-Verzeichnis neben EXE statt Prototypen-Ordner<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.28 \u2014 Sequenzen-Fenster + Design-Menu + Audio-Fix (2026-03-11)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Neues dockbares Fenster &#8222;Sequenzen&#8220; (Dock 9, getabbt mit Lyrics)<\/li>\n\n\n\n<li>Import von 885 Singing-Call-Sequenzen aus Access-MDB (caller.mdb)<\/li>\n\n\n\n<li>Cached Live-Mapping gegen Burleson-Vocabulary (Teaching Order)<\/li>\n\n\n\n<li>Contains-Filter: Autocomplete-Suche nach enthaltenen Calls<\/li>\n\n\n\n<li>Limit-Filter: Nur Sequenzen bis zu einem bestimmten Programm-Level<\/li>\n\n\n\n<li>Lazy Loading (50er-Bloecke) fuer schnelles Scrollen<\/li>\n\n\n\n<li>Detail-Dialog mit allen Calls und Programm-Tags<\/li>\n\n\n\n<li>Remapping-Button (Zahnrad) fuer Teaching-Order-Neuberechnung<\/li>\n\n\n\n<li>Zoom [-\/+] mit Prozentanzeige (wie Lyrics-Widget)<\/li>\n\n\n\n<li>Neues Modul: sequence_mapper.py (Burleson-Mapping-Logik)<\/li>\n\n\n\n<li>DB-Erweiterung: sequences + sequence_calls Tabellen mit Indizes<\/li>\n\n\n\n<li>Design-Menu: Layout laden\/speichern\/wiederherstellen + Skin-Wechsel zur Laufzeit<\/li>\n\n\n\n<li>Benannte Layouts: Caller koennen &#8222;Live.ini&#8220;, &#8222;Workshop.ini&#8220; etc. speichern<\/li>\n\n\n\n<li>Playlist-Manager umbenannt zu &#8222;Planner&#8220; (kuerzer, ueberall umbenannt)<\/li>\n\n\n\n<li>Caller-Workflow-Guidance: Lokation \u2192 Planner-Button rot \u2192 Planner bestaetigt \u2192 Playlist fokus<\/li>\n\n\n\n<li>Audio-Fix: Persistenter Stream (kein Knacken\/Brummen bei Song-Start)<\/li>\n\n\n\n<li>WSOLA-Warmup: 200ms Einschwingphase wird als Stille ausgegeben<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.27 \u2014 <a href=\"https:\/\/callerscaddy.de\/performance-callers-caddy\/\" target=\"_blank\" data-type=\"post\" data-id=\"65\" rel=\"noreferrer noopener\">Performance-Optimierung<\/a> (2026-03-11)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Performance-Messframework mit Phase A (Baseline) und Phase B (Stresstest mit 10k Songs)<\/li>\n\n\n\n<li>Testmethodik: 10 Wiederholungen, Statistik (Mean\/StdDev\/Min\/Max), CSV-Export<\/li>\n\n\n\n<li>Pool-Tabelle im Playlist-Manager: <strong>40% schneller<\/strong> durch optimiertes Tabellen-Pattern<\/li>\n\n\n\n<li>Songliste: <strong>7% schneller<\/strong> durch gleiche Optimierung<\/li>\n\n\n\n<li>Erkenntnis: QTableWidget-Rebuild ist der Flaschenhals, nicht DB oder Sortierung<\/li>\n\n\n\n<li>Optimiertes Pattern: <code>setRowCount(0)<\/code> + <code>setRowCount(n)<\/code> + <code>setItem()<\/code> statt <code>insertRow()<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.26 \u2014 Lyrics-Anzeige (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lyrics-Widget als dockbares Fenster (getabbt mit Song-Daten)<\/li>\n\n\n\n<li>Unterstuetzte Formate: HTML\/HTM, RTF, TXT<\/li>\n\n\n\n<li>Auto-Fit: Schriftgroesse wird automatisch angepasst wenn Text auf eine Seite passt<\/li>\n\n\n\n<li>Auto-Scroll: Proportional zum Song-Fortschritt<\/li>\n\n\n\n<li>Smarte Farb-Bereinigung: Hintergruende entfernt, Sektionsfarben beibehalten<\/li>\n\n\n\n<li>Toolbar mit Auto-Scroll\/Auto-Size Toggle und Zoom +\/-<\/li>\n\n\n\n<li><a href=\"https:\/\/callerscaddy.de\/farbwechsel-via-skins\/\" target=\"_blank\" data-type=\"post\" data-id=\"71\" rel=\"noreferrer noopener\">Light Blue Skin: Zweites Farbschema (helle Oberflaeche, blaue Akzente)<\/a><\/li>\n\n\n\n<li>Muted- und Indicator-Farben fuer besseren Kontrast in beiden Skins<\/li>\n\n\n\n<li>Loop-Save-Bugfix: Snapshot-Mechanismus sichert Loop-Werte vor Song-Wechsel<\/li>\n\n\n\n<li>Gemeinsame Datenordner (music\/, lyrics\/, playlists\/) sparen Plattenplatz<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.21 \u2014 Playlist und Playlist-Manager (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PlaylistWidget: Schlank, getabbt neben Songliste, Laden\/Speichern als .txt<\/li>\n\n\n\n<li>PlaylistManagerWidget: Zwei-Panel-Ansicht mit Song-Pool und Playlist-Spiegel<\/li>\n\n\n\n<li>Song-Transfer: Doppelklick, Pfeil-Buttons, Drag &amp; Drop<\/li>\n\n\n\n<li>4 Sortierungen: Alphabetisch, Qualitaet, Zuletzt gespielt, Empfehlung<\/li>\n\n\n\n<li>Filter: Alle \/ nur Pattern \/ nur Singing<\/li>\n\n\n\n<li>Auto-Advance: Naechster Song bei Song-Ende, Stop oder Fade-Out<\/li>\n\n\n\n<li>Fade-Out: Konfigurierbarer linearer Volume-Ramp (Default 3s)<\/li>\n\n\n\n<li>Empfehlungssystem integriert (urspr. P25)<\/li>\n\n\n\n<li>Playlist-Builder integriert (urspr. P24)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.20 \u2014 Abspielhistorie (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Drei-Schichten-Architektur: play_history, song_location_stats, On-the-Fly-Berechnung<\/li>\n\n\n\n<li>&#8222;Zuletzt gespielt&#8220;-Spalte in der Songliste<\/li>\n\n\n\n<li>Lokations-bezogene Statistik (wann wurde welcher Song wo gespielt)<\/li>\n\n\n\n<li>Umbenennung: &#8222;Club&#8220; wird zu &#8222;Lokation&#8220; (generalisiert fuer Club + Special)<\/li>\n\n\n\n<li>INI-Setting fuer Datumsformat (deutsch\/amerikanisch)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.19 \u2014 Lokationen (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Club- und Special-Verwaltung als auswaehlbare Kontexte<\/li>\n\n\n\n<li>Lokationsauswahl beeinflusst Songempfehlung und Historie<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.18 \u2014 Pattern\/Singing-Modus (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Songs als Pattern, Singing oder beides markierbar<\/li>\n\n\n\n<li>Typ-Kuerzel (P\/S\/PS) in Songliste und Pool-Anzeige<\/li>\n\n\n\n<li>Filter im Playlist-Manager nach Modus<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.17 \u2014 Heutiges Tempo (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gespeichertes Tempo pro Song fuer den heutigen Abend<\/li>\n\n\n\n<li>Tempo wird beim Laden eines Songs automatisch wiederhergestellt<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.16 \u2014 Songliste mit Suche (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Songliste als QTableWidget mit Echtzeit-Suchfilter<\/li>\n\n\n\n<li>Suche ueber Titel, Label und Dateiname<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.15 \u2014 Portable Pfade (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Relative Pfade fuer Songs und Daten<\/li>\n\n\n\n<li>Anwendung kann auf USB-Stick oder zwischen Rechnern verschoben werden<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.14 \u2014 Auto-Save (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Automatisches Speichern aller Aenderungen (Song-Daten, Einstellungen)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.13 \u2014 Song-Datenmodell (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SQLite-Datenbank fuer Songs, Lokationen, Historie<\/li>\n\n\n\n<li>Song-Felder: Titel, Dateiname, Label, Qualitaet, Pattern\/Singing, Tempo<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.07 \u2014 Dock-Fenstersystem (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>QDockWidget-basiertes Fenstersystem mit freier Anordnung<\/li>\n\n\n\n<li>Fenster verschieben, andocken, stapeln, Groesse aendern<\/li>\n\n\n\n<li>Layout wird gespeichert und beim Neustart wiederhergestellt<\/li>\n\n\n\n<li>Resize-Regeln pro Fenstertyp<\/li>\n\n\n\n<li>Integriert: P8 (Ein-\/Ausblenden), P9 (Verschieben), P10 (Resize-Regeln), P11 (Docking), P12 (Layout-Persistenz)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.06 \u2014 Loop mit Tempoanpassung (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Loop-Region bleibt bei Tempowechsel stabil<\/li>\n\n\n\n<li>Eigener Streaming-WSOLA-Algorithmus (kein Rubber Band\/SoundTouch)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.05 \u2014 Loop-In \/ Loop-Out (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Markierbare Loop-Region mit Start- und Endpunkt<\/li>\n\n\n\n<li>Nahtloser Loop waehrend der Wiedergabe<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.04 \u2014 Tempo und Pitch gleichzeitig (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Unabhaengige gleichzeitige Tempo- und Pitch-Steuerung<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.03 \u2014 Pitch-Steuerung (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tonhoehe stufenlos aendern, unabhaengig vom Tempo<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.02 \u2014 Tempo-Steuerung (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wiedergabegeschwindigkeit stufenlos aendern<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.01 \u2014 MP3-Wiedergabe (2026-03)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MP3-Dateien laden und stabil abspielen<\/li>\n\n\n\n<li>Grundlegende Transportsteuerung (Play, Pause, Stop)<\/li>\n\n\n\n<li>Positionsanzeige und Seek-Slider<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Versionierung: 0.XX = Prototyp-Phase (XX = Prototyp-Nummer).Ab offiziellem Launch wird auf 2.0 umgestellt.Die Versionen 1.xx bleiben f\u00fcr die alte Version offen 0.106 \u2014 Zentrale Icons, Farben aus dem Theme (2026-06-18) Neue Features \/ Verbesserungen Bugfixes (Theme-Feinschliff) Technik 0.105 \u2014 Japanisch als dritte Sprache (2026-06-18) Neue Features Verbesserungen Technik 0.104 \u2014 Massen-L\u00f6schen gro\u00dfer Songmengen (2026-06-17) Neue &#8230; <a title=\"Release Notes &#8211; Callers Caddy\" class=\"read-more\" href=\"https:\/\/callerscaddy.de\/en\/release-notes\/\" aria-label=\"Read more about Release Notes &#8211; Callers Caddy\">Read more<\/a><\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-130","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/pages\/130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/comments?post=130"}],"version-history":[{"count":9,"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/pages\/130\/revisions"}],"predecessor-version":[{"id":654,"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/pages\/130\/revisions\/654"}],"wp:attachment":[{"href":"https:\/\/callerscaddy.de\/en\/wp-json\/wp\/v2\/media?parent=130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}