-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainWindow.xaml.cs
435 lines (399 loc) · 17.1 KB
/
MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Newtonsoft.Json;
namespace TunnelMonitor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<PersonEntry> personsInTunnel;
private DispatcherTimer checkTimer = new DispatcherTimer();
private FileSystemWatcher watcher = new FileSystemWatcher();
private string sharedFolderPath = "C:\\TunnelMonitorData";
private LogManager log = new LogManager();
public MainWindow()
{
InitializeComponent();
personsInTunnel = new ObservableCollection<PersonEntry>();
dgPersonsInTunnel.ItemsSource = personsInTunnel;
LoadDataDirPath();
// sharedFolderPath = @"C:\Users\peter\OneDrive\Dokumenter\projects\TunnelMonitorData";
LoadExistingPersons();
if (string.IsNullOrEmpty(sharedFolderPath))
{
return;
}
log.LogPath = sharedFolderPath;
// Initialiser og start DispatcherTimer
checkTimer.Interval = TimeSpan.FromSeconds(30); // Tjek hver 30. sekund
checkTimer.Tick += CheckTimer_Tick;
checkTimer.Start();
// Initialiser og start FileSystemWatcher
watcher.Path = sharedFolderPath;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.txt";
watcher.Changed += OnChanged;
watcher.EnableRaisingEvents = true;
// Indlæs eksisterende personfiler ved opstart
}
private void CheckTimer_Tick(object? sender, EventArgs e)
{
// Gennemgå hver person i listen og tjek deres forventede returtid
foreach (var person in personsInTunnel)
{
if (DateTime.Now > person.ExpectedReturnTime && !person.IsOverdue)
{
// Marker personen som overdue
person.IsOverdue = true;
}
else if (DateTime.Now <= person.ExpectedReturnTime && person.IsOverdue)
{
// Fjern overdue markeringen, hvis personen ikke længere er overdue
person.IsOverdue = false;
}
}
// Opdater UI trådsikkert
Dispatcher.Invoke(() =>
{
dgPersonsInTunnel.Items.Refresh();
});
}
private void txtName_TextChanged(object sender, TextChangedEventArgs e)
{
// Tjek om tekstboksen for navn har nogen tekst
if (!string.IsNullOrWhiteSpace(txtName.Text))
{
// Sæt den nuværende tid i 'Indgangstid', hvis den ikke allerede er sat
if (string.IsNullOrWhiteSpace(txtEntryTime.Text))
{
txtEntryTime.Text = DateTime.Now.ToString("dd-MM-yyyy HH:mm");
}
// Sæt tiden for 'Forventet retur' til en time senere, hvis den ikke allerede er sat
if (string.IsNullOrWhiteSpace(txtExpectedReturnTime.Text))
{
txtExpectedReturnTime.Text = DateTime
.Now
.AddHours(1)
.ToString("dd-MM-yyyy HH:mm");
}
txtNumber.Text = "1";
}
}
private void OnChanged(object source, FileSystemEventArgs e)
{
Application
.Current
.Dispatcher
.Invoke(() =>
{
try
{
string fileName = System.IO.Path.GetFileName(e.FullPath);
// Find personen i samlingen baseret på filnavnet
var person = personsInTunnel.FirstOrDefault(p => p.FileName == fileName);
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
if (person != null)
{
personsInTunnel.Remove(person);
}
}
else // Hvis filen er blevet oprettet eller ændret
{
string[] lines = File.ReadAllLines(e.FullPath);
var personData = new Dictionary<string, string>();
foreach (var line in lines)
{
var keyValue = line.Split(new[] { ':' }, 2);
if (keyValue.Length == 2)
{
personData[keyValue[0].Trim()] = keyValue[1].Trim();
}
}
string name = personData["Name"];
string phone = personData["Phone"];
string company = personData["Company"];
int numberOfPersons = int.Parse(personData["NumberOfPersons"]);
bool isTunnel1Checked = personData["Tunnel1"] == "True";
bool isTunnel2Checked = personData["Tunnel2"] == "True";
DateTime entryTime = DateTime.Parse(personData["EntryTime"]);
DateTime expectedReturn = DateTime.Parse(
personData["ExpectedReturnTime"]
);
if (person == null) // Hvis personen ikke findes, tilføj dem
{
person = new PersonEntry(
name,
phone,
company,
numberOfPersons,
isTunnel1Checked,
isTunnel2Checked,
entryTime,
expectedReturn,
fileName
);
personsInTunnel.Add(person);
}
else // Hvis personen allerede findes, opdater deres oplysninger
{
person.Company = company;
person.EntryTime = entryTime;
person.NumberOfPersons = numberOfPersons;
person.IsTunnel1Checked = isTunnel1Checked;
person.IsTunnel2Checked = isTunnel2Checked;
person.ExpectedReturnTime = expectedReturn;
person.IsOverdue = DateTime.Now > expectedReturn;
}
}
}
catch
{
// Håndter eventuelle IO fejl
}
});
}
private void btnAddPerson_Click(object sender, RoutedEventArgs e)
{
// Valider input (du kan tilføje mere avanceret validering efter behov)
// Tjekker for tomme felter
if (string.IsNullOrWhiteSpace(txtName.Text))
{
MessageBox.Show("The name field must not be empty.");
return;
}
if (string.IsNullOrWhiteSpace(txtPhone.Text))
{
MessageBox.Show("The phone field must not be empty.");
return;
}
if (string.IsNullOrWhiteSpace(txtCompany.Text))
{
MessageBox.Show("The company field must not be empty.");
return;
}
if (string.IsNullOrWhiteSpace(txtNumber.Text))
{
MessageBox.Show("The number field must not be empty.");
return;
}
if (!int.TryParse(txtNumber.Text, out int numberOfPersons))
{
// Handle the error if the text is not a valid integer
MessageBox.Show("Please enter a valid number of persons.");
return;
}
if (chkTunnel1.IsChecked == false && chkTunnel2.IsChecked == false)
{
MessageBox.Show("Please select a tunnel.");
return;
}
// Validerer datoer med et specifikt format
string dateFormat = "dd-MM-yyyy HH:mm";
if (
!DateTime.TryParseExact(
txtEntryTime.Text,
dateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime entryTime
)
)
{
MessageBox.Show("Entry time has an invalid format. Use the format: " + dateFormat);
return;
}
if (
!DateTime.TryParseExact(
txtExpectedReturnTime.Text,
dateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime expectedReturnTime
)
)
{
MessageBox.Show(
"The expected return date has an invalid format. Use the format: " + dateFormat
);
return;
}
// Hvis koden når her, er alle felter validerede uden fejl.
// Opret en ny PersonEntry
var newPerson = new PersonEntry(
txtName.Text,
txtPhone.Text,
txtCompany.Text,
numberOfPersons,
chkTunnel1.IsChecked ?? false,
chkTunnel2.IsChecked ?? false,
entryTime,
expectedReturnTime
);
// Tilføj den nye person til ObservableCollection
personsInTunnel.Add(newPerson);
log.LogEntry(newPerson);
// Gem personens data til den delte fil
SavePersonToFile(newPerson);
// Ryd inputfelterne
txtName.Clear();
txtPhone.Clear();
txtCompany.Clear();
txtNumber.Clear();
chkTunnel1.IsChecked = false;
chkTunnel2.IsChecked = false;
txtEntryTime.Clear();
txtExpectedReturnTime.Clear();
}
private void RemovePerson_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var person = button?.DataContext as PersonEntry;
if (person != null)
{
personsInTunnel.Remove(person);
File.Delete(System.IO.Path.Combine(sharedFolderPath, person.FileName));
log.LogExit(person);
}
}
private void LoadExistingPersons()
{
// Tjek om mappen eksisterer
if (Directory.Exists(sharedFolderPath))
{
// Hent alle .txt filer i mappen
var files = Directory.GetFiles(sharedFolderPath, "*.txt");
foreach (var file in files)
{
try
{
// Læs filen og skab et PersonEntry objekt
string[] lines = File.ReadAllLines(file);
var personData = new Dictionary<string, string>();
foreach (var line in lines)
{
var keyValue = line.Split(new[] { ':' }, 2);
if (keyValue.Length == 2)
{
personData[keyValue[0].Trim()] = keyValue[1].Trim();
}
}
// Antag at alle nødvendige nøgler findes for enkelhedens skyld
var name = personData["Name"];
var phone = personData["Phone"];
var company = personData["Company"];
var numberOfPersons = int.Parse(personData["NumberOfPersons"]);
var isTunnel1Checked = personData["Tunnel1"] == "True";
var isTunnel2Checked = personData["Tunnel2"] == "True";
var entryTime = DateTime.ParseExact(
personData["EntryTime"],
"dd-MM-yyyy HH:mm",
CultureInfo.InvariantCulture
);
var expectedReturn = DateTime.ParseExact(
personData["ExpectedReturnTime"],
"dd-MM-yyyy HH:mm",
CultureInfo.InvariantCulture
);
// Opret et nyt PersonEntry objekt og tilføj det til kollektionen
var personEntry = new PersonEntry(
name,
phone,
company,
numberOfPersons,
isTunnel1Checked,
isTunnel2Checked,
entryTime,
expectedReturn,
System.IO.Path.GetFileName(file)
);
personsInTunnel.Add(personEntry);
}
catch (Exception)
{
MessageBox.Show("Error loading person data from: " + file);
}
}
}
Dispatcher.Invoke(() =>
{
dgPersonsInTunnel.Items.Refresh();
});
}
// }
private void SavePersonToFile(PersonEntry person)
{
// Sti til den delte mappe
// Generer filnavnet baseret på personens data
string fileName = person.FileName;
// Skriv personens data til filen i det angivne format
var sb = new StringBuilder();
sb.AppendLine($"Name: {person.Name}");
sb.AppendLine($"Phone: {person.Phone}");
sb.AppendLine($"Company: {person.Company}");
sb.AppendLine($"NumberOfPersons: {person.NumberOfPersons}");
sb.AppendLine($"Tunnel1: {person.IsTunnel1Checked.ToString()}");
sb.AppendLine($"Tunnel2: {person.IsTunnel2Checked.ToString()}");
sb.AppendLine($"EntryTime: {person.EntryTime:dd-MM-yyyy HH:mm}");
sb.AppendLine($"ExpectedReturnTime: {person.ExpectedReturnTime:dd-MM-yyyy HH:mm}");
// Gem dataene til filen
File.WriteAllText(System.IO.Path.Combine(sharedFolderPath, fileName), sb.ToString());
}
private void LoadDataDirPath()
{
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string settingsDirectoryPath = System.IO.Path.Combine(appDataPath, "TunnelMonitor");
string settingsFilePath = System.IO.Path.Combine(settingsDirectoryPath, "settings.json");
// Kontroller, om settings.json filen eksisterer
if (File.Exists(settingsFilePath))
{
// Parse JSON fra filen
string jsonContent = File.ReadAllText(settingsFilePath);
var settings = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonContent);
// Antager at der er en nøgle i JSON kaldet 'SharedFolderPath'
if (settings != null && settings.ContainsKey("DataDir"))
{
sharedFolderPath = settings["DataDir"].Replace("%HOMEDIR%", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
Directory.CreateDirectory(sharedFolderPath);
}
else
{
// Hvis nøglen ikke findes, håndter fejlen
MessageBox.Show("Nøglen 'DataDir' blev ikke fundet i settings.json.");
}
}
else
{
// Filen findes ikke, så vis en fejlbesked
MessageBox.Show(
@"Filen ""TunnelMonitor/settings.json"" findes ikke.
Gå til " + settingsDirectoryPath + @"
Opret ""settings.json"" og skriv JSON-indholdet med nødvendige indstillinger.
Eksempel på indhold i 'settings.json':
{
""SharedFolderPath"": ""E:\\TunnelMonitorData""
}"
);
}
}
}
}