Release SyncVito 1.0.11

This commit is contained in:
Davito committed 2026-09-27 22:42:23 +02:00
1 parent 7098fa1c0c
commit ccb89191b5
6 files changed
+62 -8

No files matched your search

+10
View File
@@ -1,5 +1,15 @@
# Änderungsprotokoll # Änderungsprotokoll
## 1.0.11 – 2026-09-27
### Behoben
- Der Button „Pausieren“ ist im Leerlauf deaktiviert, damit SyncVito nicht versehentlich ohne aktive Aufgabe in den Pausenzustand versetzt werden kann.
- Beim Klick auf „Alle jetzt synchronisieren“ oder „Auswahl synchronisieren“ wird ein eventuell aktiver Pausenzustand automatisch aufgehoben und der Lauf sofort gestartet.
- Klickt man auf „Fortsetzen“, wenn zuvor noch keine Aufgabe eingereiht war, startet SyncVito direkt alle aktiven Aufgaben, statt wirkungslos zu bleiben.
- Die automatische Hintergrund-Updateprüfung setzt die Fortschrittsleiste im Leerlauf nicht mehr dauerhaft auf 100 % mit „SyncVito ist aktuell“, sondern die Leiste bleibt ordnungsgemäß auf „Bereit“.
- Die Tray-Benachrichtigung beim Schließen des Fensters lautet nun unmissverständlich „SyncVito minimiert“ statt „SyncVito läuft weiter“.
## 1.0.10 – 2026-09-27 ## 1.0.10 – 2026-09-27
### Neu ### Neu
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "syncvito" name = "syncvito"
version = "1.0.10" version = "1.0.11"
description = "Windows-Desktopwerkzeug für lokale und NAS-Synchronisation" description = "Windows-Desktopwerkzeug für lokale und NAS-Synchronisation"
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
+6
View File
@@ -194,6 +194,8 @@ class SyncCoordinator(QObject):
def enqueue_all(self) -> None: def enqueue_all(self) -> None:
"""Stellt alle aktiven Aufgaben zur manuellen Ausführung an.""" """Stellt alle aktiven Aufgaben zur manuellen Ausführung an."""
if self.config.settings.paused:
self.set_paused(False)
for task in self.config.tasks: for task in self.config.tasks:
if task.enabled: if task.enabled:
self.enqueue(task.id) self.enqueue(task.id)
@@ -213,6 +215,10 @@ class SyncCoordinator(QObject):
for tid in self.config.settings.pending_queue: for tid in self.config.settings.pending_queue:
if tid not in self._queue and any(t.id == tid and t.enabled for t in self.config.tasks): if tid not in self._queue and any(t.id == tid and t.enabled for t in self.config.tasks):
self._queue.append(tid) self._queue.append(tid)
if not self._queue and not self._running_task_id:
for task in self.config.tasks:
if task.enabled:
self._queue.append(task.id)
self._start_next() self._start_next()
with suppress(Exception): with suppress(Exception):
self.config_store.save(self.config) self.config_store.save(self.config)
+30 -6
View File
@@ -140,8 +140,8 @@ class MainWindow(QMainWindow):
event.ignore() event.ignore()
self.hide() self.hide()
self.tray.showMessage( self.tray.showMessage(
"SyncVito läuft weiter", "SyncVito minimiert",
"Das Fenster wurde in den Infobereich verschoben.", "SyncVito bleibt im Infobereich aktiv.",
QSystemTrayIcon.MessageIcon.Information, QSystemTrayIcon.MessageIcon.Information,
2500, 2500,
) )
@@ -572,6 +572,8 @@ class MainWindow(QMainWindow):
if task is None: if task is None:
QMessageBox.information(self, "Keine Auswahl", "Bitte zuerst eine Aufgabe auswählen.") QMessageBox.information(self, "Keine Auswahl", "Bitte zuerst eine Aufgabe auswählen.")
return return
if self.config.settings.paused:
self.coordinator.set_paused(False)
self.coordinator.enqueue(task.id) self.coordinator.enqueue(task.id)
def _persist_tasks(self, message: str) -> None: def _persist_tasks(self, message: str) -> None:
@@ -652,10 +654,18 @@ class MainWindow(QMainWindow):
self._mark_update_checked() self._mark_update_checked()
self._set_update_indicator(None) self._set_update_indicator(None)
self._notified_update_version = None self._notified_update_version = None
self._update_progress(100, "SyncVito ist aktuell")
self._append_log("Update", "Erfolg", "Die installierte Version ist aktuell.") self._append_log("Update", "Erfolg", "Die installierte Version ist aktuell.")
if manual: if manual:
self._update_progress(100, "SyncVito ist aktuell")
QMessageBox.information(self, "Keine Updates", "Du verwendest bereits die aktuelle SyncVito-Version.") QMessageBox.information(self, "Keine Updates", "Du verwendest bereits die aktuelle SyncVito-Version.")
elif not self.coordinator.is_running:
self.progress_text.setText("SyncVito ist aktuell")
QTimer.singleShot(3000, self._reset_idle_progress)
def _reset_idle_progress(self) -> None:
if not self.coordinator.is_running and not self.config.settings.paused:
self.progress_text.setText("Bereit")
self.progress_bar.setValue(0)
def _on_update_error(self, message: str, manual: bool) -> None: def _on_update_error(self, message: str, manual: bool) -> None:
self._update_progress(0, "Updateprüfung fehlgeschlagen") self._update_progress(0, "Updateprüfung fehlgeschlagen")
@@ -740,18 +750,32 @@ class MainWindow(QMainWindow):
def _update_pause_action(self) -> None: def _update_pause_action(self) -> None:
is_paused = self.config.settings.paused is_paused = self.config.settings.paused
is_running = self.coordinator.is_running
has_queue = bool(self.coordinator.queued_task_ids)
if is_paused: if is_paused:
btn_text = "▶ Fortsetzen" btn_text = "▶ Fortsetzen"
tray_text = "Fortsetzen" tray_text = "Fortsetzen"
else: btn_enabled = True
btn_text = "⏸ Pausieren" if self.coordinator.is_running else "Pausieren" primary = True
elif is_running or has_queue:
btn_text = "⏸ Pausieren"
tray_text = "Pausieren" tray_text = "Pausieren"
btn_enabled = True
primary = False
else:
btn_text = "Pausieren"
tray_text = "Pausieren"
btn_enabled = False
primary = False
self.pause_action.setText(tray_text) self.pause_action.setText(tray_text)
self.pause_action.setEnabled(btn_enabled)
for btn in (getattr(self, "header_pause_button", None), getattr(self, "dock_pause_button", None)): for btn in (getattr(self, "header_pause_button", None), getattr(self, "dock_pause_button", None)):
if btn is not None: if btn is not None:
btn.setText(btn_text) btn.setText(btn_text)
btn.setProperty("primary", is_paused) btn.setEnabled(btn_enabled)
btn.setProperty("primary", primary)
btn.style().unpolish(btn) btn.style().unpolish(btn)
btn.style().polish(btn) btn.style().polish(btn)
+14
View File
@@ -137,3 +137,17 @@ def test_stop_persists_running_task_and_queue_for_restart(coordinator: SyncCoord
assert coordinator.config.settings.paused is True assert coordinator.config.settings.paused is True
assert coordinator.config.settings.pending_queue == [task1.id, task2.id] assert coordinator.config.settings.pending_queue == [task1.id, task2.id]
def test_enqueue_all_unpauses_and_runs(coordinator: SyncCoordinator) -> None:
from types import SimpleNamespace
coordinator.set_paused(True)
workers = []
coordinator.pool = SimpleNamespace(start=workers.append)
coordinator.enqueue_all()
assert not coordinator.config.settings.paused
assert len(workers) == 1
assert coordinator.running_task_id == coordinator.config.tasks[0].id
+1 -1
View File
@@ -1 +1 @@
1.0.10 1.0.11