diff --git a/CHANGELOG.md b/CHANGELOG.md
index 078e093b..b3e5eba0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,11 @@ Versionsschema ist `x.x.x.x` (siehe `release.sh`).
### Hinzugefuegt
+- **Protokoll automatisch leeren (Einstellung).** Neuer Wert "Protokoll
+ auto-leeren - Eintraege aelter als (Tage)". Bei 0 (Standard) bleibt alles
+ erhalten; bei >0 werden aeltere Eintraege automatisch entfernt (beim Start,
+ vor jedem Sync, beim Oeffnen des Protokolls und beim Speichern der
+ Einstellungen).
- **Protokoll zeigt jetzt, WAS geaendert wurde.** Pro Sync werden die einzelnen
Aktionen (erstellt / aktualisiert / geloescht / verknuepft / zusammengefuehrt je
Kontakt) ins Protokoll geschrieben - sowohl beim manuellen Sync (Fenster) als
diff --git a/src/StarfaceOutlookSync/Models/UserSettings.cs b/src/StarfaceOutlookSync/Models/UserSettings.cs
index 5877679a..a75b9ac0 100644
--- a/src/StarfaceOutlookSync/Models/UserSettings.cs
+++ b/src/StarfaceOutlookSync/Models/UserSettings.cs
@@ -16,6 +16,10 @@ namespace StarfaceOutlookSync.Models
public bool NotificationsEnabled { get; set; } = true;
public bool NotifyWarningsErrors { get; set; } = true;
+ // Protokoll-Eintraege aelter als X Tage automatisch entfernen. 0 = aus
+ // (alle Eintraege bleiben erhalten).
+ public int LogRetentionDays { get; set; } = 0;
+
// Gemeinsames Verzeichnis (Netzlaufwerk/UNC) fuer die clientuebergreifende
// Sync-Sperre. Leer = keine Sperre (nur lokaler Schutz). Verhindert, dass
// mehrere Arbeitsplaetze gleichzeitig dasselbe Adressbuch synchronisieren.
diff --git a/src/StarfaceOutlookSync/Services/Logger.cs b/src/StarfaceOutlookSync/Services/Logger.cs
index e0f3f9c4..014c4de0 100644
--- a/src/StarfaceOutlookSync/Services/Logger.cs
+++ b/src/StarfaceOutlookSync/Services/Logger.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Text;
@@ -63,6 +65,48 @@ namespace StarfaceOutlookSync.Services
catch { return ""; }
}
+ ///
+ /// Entfernt Protokoll-Eintraege, die aelter als
+ /// Tage sind. days <= 0 -> nichts tun (alle Eintraege bleiben).
+ ///
+ public static void PruneOlderThan(int days)
+ {
+ if (days <= 0) return;
+ try
+ {
+ lock (_lock)
+ {
+ if (!File.Exists(LogFilePath)) return;
+ var cutoff = DateTime.Now.AddDays(-days);
+ var lines = File.ReadAllLines(LogFilePath, Encoding.UTF8);
+ var kept = new List(lines.Length);
+ foreach (var line in lines)
+ {
+ // Eintraege ohne erkennbaren Zeitstempel (z.B. Fortsetzungs-
+ // zeilen) bleiben erhalten; nur datierte Alt-Eintraege fliegen raus.
+ if (TryParseLineDate(line, out var dt) && dt < cutoff)
+ continue;
+ kept.Add(line);
+ }
+ if (kept.Count != lines.Length)
+ File.WriteAllLines(LogFilePath, kept, Encoding.UTF8);
+ }
+ }
+ catch { }
+ }
+
+ private static bool TryParseLineDate(string line, out DateTime dt)
+ {
+ dt = default;
+ // Format: "[yyyy-MM-dd HH:mm:ss] ..."
+ if (line != null && line.Length >= 21 && line[0] == '[' && line[20] == ']')
+ {
+ return DateTime.TryParseExact(line.Substring(1, 19), "yyyy-MM-dd HH:mm:ss",
+ CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
+ }
+ return false;
+ }
+
public static void Clear()
{
try
diff --git a/src/StarfaceOutlookSync/Services/SyncCoordinator.cs b/src/StarfaceOutlookSync/Services/SyncCoordinator.cs
index ac3ad821..98850f69 100644
--- a/src/StarfaceOutlookSync/Services/SyncCoordinator.cs
+++ b/src/StarfaceOutlookSync/Services/SyncCoordinator.cs
@@ -53,7 +53,9 @@ namespace StarfaceOutlookSync.Services
}
SyncLock crossLock = null;
- var sharedDir = UserSettings.Load().SharedDirectory;
+ var settings = UserSettings.Load();
+ Logger.PruneOlderThan(settings.LogRetentionDays);
+ var sharedDir = settings.SharedDirectory;
try
{
crossLock = await AcquireCrossClientLock(sharedDir, status);
diff --git a/src/StarfaceOutlookSync/UI/LogViewerForm.cs b/src/StarfaceOutlookSync/UI/LogViewerForm.cs
index 034c3760..fd69b3f9 100644
--- a/src/StarfaceOutlookSync/UI/LogViewerForm.cs
+++ b/src/StarfaceOutlookSync/UI/LogViewerForm.cs
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
+using StarfaceOutlookSync.Models;
using StarfaceOutlookSync.Services;
namespace StarfaceOutlookSync.UI
@@ -72,6 +73,7 @@ namespace StarfaceOutlookSync.UI
private void LoadLog()
{
+ Logger.PruneOlderThan(UserSettings.Load().LogRetentionDays);
_txt.Text = Logger.ReadAll();
_txt.SelectionStart = _txt.TextLength;
_txt.ScrollToCaret();
diff --git a/src/StarfaceOutlookSync/UI/MainForm.cs b/src/StarfaceOutlookSync/UI/MainForm.cs
index fc79387d..570ad1bf 100644
--- a/src/StarfaceOutlookSync/UI/MainForm.cs
+++ b/src/StarfaceOutlookSync/UI/MainForm.cs
@@ -39,6 +39,9 @@ namespace StarfaceOutlookSync.UI
var settings = UserSettings.Load();
settings.ApplyOutlookSecuritySetting();
+ // Protokoll bei Bedarf auf das eingestellte Alter eindampfen.
+ Logger.PruneOlderThan(settings.LogRetentionDays);
+
if (settings.StartMinimized)
{
WindowState = FormWindowState.Minimized;
diff --git a/src/StarfaceOutlookSync/UI/SettingsForm.cs b/src/StarfaceOutlookSync/UI/SettingsForm.cs
index 6c25d408..ca1afd0f 100644
--- a/src/StarfaceOutlookSync/UI/SettingsForm.cs
+++ b/src/StarfaceOutlookSync/UI/SettingsForm.cs
@@ -1,6 +1,7 @@
using System.Drawing;
using System.Windows.Forms;
using StarfaceOutlookSync.Models;
+using StarfaceOutlookSync.Services;
namespace StarfaceOutlookSync.UI
{
@@ -8,6 +9,7 @@ namespace StarfaceOutlookSync.UI
{
private CheckBox _chkStartMinimized, _chkSyncOnStart, _chkAutoAcceptOutlook;
private CheckBox _chkNotifGeneral, _chkNotifWarn;
+ private NumericUpDown _numLogRetention;
private TextBox _txtSharedDir;
private Button _btnBrowseShared;
private Button _btnSave, _btnCancel;
@@ -76,21 +78,33 @@ namespace StarfaceOutlookSync.UI
Checked = _settings.NotifyWarningsErrors
};
+ var lblLogRetention = new Label
+ {
+ Text = "Protokoll auto-leeren - Eintraege aelter als (Tage, 0 = aus):",
+ Left = 20, Top = 204, AutoSize = true
+ };
+
+ _numLogRetention = new NumericUpDown
+ {
+ Left = 305, Top = 200, Width = 55, Minimum = 0, Maximum = 3650,
+ Value = System.Math.Max(0, System.Math.Min(3650, _settings.LogRetentionDays))
+ };
+
var lblShared = new Label
{
Text = "Gemeinsames Verzeichnis fuer Sync-Sperre (Mehrplatz, optional):",
- Left = 20, Top = 206, AutoSize = true
+ Left = 20, Top = 240, AutoSize = true
};
_txtSharedDir = new TextBox
{
- Left = 20, Top = 228, Width = 250,
+ Left = 20, Top = 262, Width = 250,
Text = _settings.SharedDirectory
};
_btnBrowseShared = new Button
{
- Text = "...", Left = 274, Top = 227, Width = 36, Height = 24
+ Text = "...", Left = 274, Top = 261, Width = 36, Height = 24
};
_btnBrowseShared.Click += (s, e) => BrowseSharedDir();
@@ -98,26 +112,26 @@ namespace StarfaceOutlookSync.UI
{
Text = "Netzlaufwerk/UNC, das alle Arbeitsplaetze erreichen. Leer = keine\n" +
"clientuebergreifende Sperre (nur Schutz auf diesem PC).",
- Left = 20, Top = 254, Width = 330, Height = 32,
+ Left = 20, Top = 288, Width = 330, Height = 32,
ForeColor = Color.Gray, Font = new Font("Segoe UI", 8)
};
_btnSave = new Button
{
- Text = "Speichern", Left = 95, Top = 300, Width = 85, Height = 28,
+ Text = "Speichern", Left = 95, Top = 334, Width = 85, Height = 28,
DialogResult = DialogResult.None
};
_btnSave.Click += (s, e) => Save();
_btnCancel = new Button
{
- Text = "Abbrechen", Left = 189, Top = 300, Width = 85, Height = 28,
+ Text = "Abbrechen", Left = 189, Top = 334, Width = 85, Height = 28,
DialogResult = DialogResult.Cancel
};
- Size = new Size(380, 390);
+ Size = new Size(380, 424);
Controls.AddRange(new Control[] { _chkStartMinimized, _chkSyncOnStart, _chkAutoAcceptOutlook, lblHint,
- _chkNotifGeneral, _chkNotifWarn,
+ _chkNotifGeneral, _chkNotifWarn, lblLogRetention, _numLogRetention,
lblShared, _txtSharedDir, _btnBrowseShared, lblSharedHint, _btnSave, _btnCancel });
AcceptButton = _btnSave;
CancelButton = _btnCancel;
@@ -144,8 +158,13 @@ namespace StarfaceOutlookSync.UI
_settings.AutoAcceptOutlookPrompt = _chkAutoAcceptOutlook.Checked;
_settings.NotificationsEnabled = _chkNotifGeneral.Checked;
_settings.NotifyWarningsErrors = _chkNotifWarn.Checked;
+ _settings.LogRetentionDays = (int)_numLogRetention.Value;
_settings.SharedDirectory = _txtSharedDir.Text.Trim();
_settings.Save();
+
+ // Sofort anwenden, damit der Effekt direkt sichtbar ist.
+ Logger.PruneOlderThan(_settings.LogRetentionDays);
+
DialogResult = DialogResult.OK;
Close();
}