Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
WorkspaceSettings.cs
1using CommunityToolkit.Mvvm.ComponentModel;
4
6{
10 public class WorkspaceSettings : ObservableObject, IEquatable<WorkspaceSettings>, ICloneable
11 {
12 #region Group / Setting keys
13
14 public const string GROUP_GENERAL = "General";
15 public const string SETTING_GENERAL_COMPETITIONYEAR = "CompetitionYear";
16 public const string SETTING_GENERAL_COMPETITIONDATE = "CompetitionDate";
17 public const string SETTING_GENERAL_COMPETITIONSEARCHMODE = "CompetitionSearchMode";
18 public const string SETTING_GENERAL_TIMEINPUT_NUMBER_MILLISECOND_DIGITS = "TimeInputMillisecondDigits";
19 public const string SETTING_GENERAL_SCORE_FRACTIONAL_DIGITS = "ScoreFractionalDigits";
20
21 public const string GROUP_RACE_CALCULATION = "RaceCalculation";
22 public const string SETTING_RACE_CALCULATION_NUMBER_OF_SWIM_LANES = "NumberOfSwimLanes";
23 public const string SETTING_RACE_CALCULATION_NUM_RACE_VARIANTS_AFTER_CALCULATION = "NumberRacesVariantsAfterCalculation";
24 public const string SETTING_RACE_CALCULATION_MAX_CALCULATION_LOOPS = "MaxRacesVariantCalculationLoops";
25 public const string SETTING_RACE_CALCULATION_MIN_RACES_VARIANTS_SCORE = "MinRacesVariantsScore";
26 public const string SETTING_RACE_CALCULATION_WEIGHT_SINGLE_STARTS = "WeightSingleStarts";
27 public const string SETTING_RACE_CALCULATION_WEIGHT_SAME_STYLE_SEQUENCE = "WeightSameStyleSequence";
28 public const string SETTING_RACE_CALCULATION_WEIGHT_PERSON_START_PAUSES = "WeightPersonStartPauses";
29 public const string SETTING_RACE_CALCULATION_WEIGHT_STYLE_ORDER = "WeightStyleOrder";
30 public const string SETTING_RACE_CALCULATION_WEIGHT_START_GENDERS = "WeightStartGenders";
31 public const string SETTING_RACE_CALCULATION_WEIGHT_FRIENDSHIP = "WeightFriendship";
32 public const string SETTING_RACE_CALCULATION_SHORT_PAUSE_THRESHOLD = "ShortPauseThreshold";
33 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_BREASTSTROKE = "PriorityStyleBreaststroke";
34 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_FREESTYLE = "PriorityStyleFreestyle";
35 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_BACKSTROKE = "PriorityStyleBackstroke";
36 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_BUTTERFLY = "PriorityStyleButterfly";
37 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_MEDLEY = "PriorityStyleMedley";
38 public const string SETTING_RACE_CALCULATION_PRIORITY_STYLE_WATERFLEA = "PriorityStyleWaterflea";
39
40 public const string GROUP_DOCUMENT_CREATION = "DocumentCreation";
41 public const string SETTING_DOCUMENT_CREATION_PLACEHOLDER_MARKER = "PlaceholderMarker";
42 public const string SETTING_DOCUMENT_CREATION_TEMPLATE_FILENAME_POSTFIX = "TemplateFilenamePostfix";
43 public const string SETTING_DOCUMENT_CREATION_OUTPUT_FOLDER = "DocumentOutputFolder";
44 public const string SETTING_DOCUMENT_CREATION_CERTIFICATE_TEMPLATE_PATH = "CertificateTemplatePath";
45 public const string SETTING_DOCUMENT_CREATION_OVERVIEW_LIST_TEMPLATE_PATH = "OverviewlistTemplatePath";
46 public const string SETTING_DOCUMENT_CREATION_RACE_START_LIST_TEMPLATE_PATH = "RaceStartListTemplatePath";
47 public const string SETTING_DOCUMENT_CREATION_TIME_FORMS_TEMPLATE_PATH = "TimeFormsTemplatePath";
48 public const string SETTING_DOCUMENT_CREATION_RESULT_LIST_TEMPLATE_PATH = "ResultListTemplatePath";
49 public const string SETTING_DOCUMENT_CREATION_RESULT_LIST_DETAIL_TEMPLATE_PATH = "ResultListDetailTemplatePath";
50 public const string SETTING_DOCUMENT_CREATION_ANALYTICS_TEMPLATE_PATH = "AnalyticsTemplatePath";
51 public const string SETTING_DOCUMENT_CREATION_FILE_TYPES = "DocumentFileTypes";
52
53 //... Add new setting keys and group keys here ...
54
55 #endregion
56
57 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58
59 #region Init Settings
60
64 public const string DEFAULT_TEMPLATE_FOLDER_NAME = "Templates";
65
69 private void initializeSettings()
70 {
71 // Initialize groups if not already initialized
72
73 // +++++ Group General +++++
74 WorkspaceSettingsGroup groupGeneral = GetGroup(GROUP_GENERAL, true);
75 groupGeneral.MakeSureSettingExists<ushort>(SETTING_GENERAL_COMPETITIONYEAR, 0, 1900, 3000);
76 groupGeneral.MakeSureSettingExists<DateTime>(SETTING_GENERAL_COMPETITIONDATE, new DateTime(1900, 01, 01), new DateTime(1900, 01, 01), new DateTime(3000, 12, 31));
77 groupGeneral.MakeSureSettingExists<CompetitionSearchModes>(SETTING_GENERAL_COMPETITIONSEARCHMODE, CompetitionSearchModes.ExactOrNextLowerOnlyMaxAge);
78 groupGeneral.MakeSureSettingExists<ushort>(SETTING_GENERAL_TIMEINPUT_NUMBER_MILLISECOND_DIGITS, 2, 1, 3);
79 groupGeneral.MakeSureSettingExists<ushort>(SETTING_GENERAL_SCORE_FRACTIONAL_DIGITS, 1, 0, 5);
80
81 // +++++ Group Race Calculation +++++
82 WorkspaceSettingsGroup groupRaceCalculation = GetGroup(GROUP_RACE_CALCULATION, true);
83 groupRaceCalculation.MakeSureSettingExists<ushort>(SETTING_RACE_CALCULATION_NUMBER_OF_SWIM_LANES, 3, 0, 10);
84 groupRaceCalculation.MakeSureSettingExists<ushort>(SETTING_RACE_CALCULATION_NUM_RACE_VARIANTS_AFTER_CALCULATION, 100, 1, 1000);
85 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_MAX_CALCULATION_LOOPS, 1000000, 1, int.MaxValue);
86 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_MIN_RACES_VARIANTS_SCORE, 90.0, 0.0, 100.0);
87 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_SINGLE_STARTS, 15.0, 0.0, 100.0);
88 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_SAME_STYLE_SEQUENCE, 5.0, 0.0, 100.0);
89 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_PERSON_START_PAUSES, 60.0, 0.0, 100.0);
90 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_STYLE_ORDER, 10.0, 0.0, 100.0);
91 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_START_GENDERS, 5.0, 0.0, 100.0);
92 groupRaceCalculation.MakeSureSettingExists<double>(SETTING_RACE_CALCULATION_WEIGHT_FRIENDSHIP, 5.0, 0.0, 100.0);
93 groupRaceCalculation.MakeSureSettingExists<uint>(SETTING_RACE_CALCULATION_SHORT_PAUSE_THRESHOLD, 3u, 1u, 100u);
94 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_BREASTSTROKE, 1, 1, 6); // The lower the number the higher the priority
95 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_FREESTYLE, 2, 1, 6);
96 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_BACKSTROKE, 3, 1, 6);
97 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_BUTTERFLY, 4, 1, 6);
98 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_MEDLEY, 5, 1, 6);
99 groupRaceCalculation.MakeSureSettingExists<int>(SETTING_RACE_CALCULATION_PRIORITY_STYLE_WATERFLEA, 6, 1, 6);
100
101 // +++++ Group Document Creation +++++
102 WorkspaceSettingsGroup groupDocumentCreation = GetGroup(GROUP_DOCUMENT_CREATION, true);
103 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_PLACEHOLDER_MARKER, "%");
104 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_TEMPLATE_FILENAME_POSTFIX, "_Template");
105 groupDocumentCreation.MakeSureSettingExists<DocumentCreationFileTypes>(SETTING_DOCUMENT_CREATION_FILE_TYPES, DocumentCreationFileTypes.DOCX_AND_PDF);
106 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_OUTPUT_FOLDER, @"Dokumente");
107 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_CERTIFICATE_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Urkunden_Template.docx");
108 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_OVERVIEW_LIST_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Gesamtliste_Template.docx");
109 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_RACE_START_LIST_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Startliste_Template.docx");
110 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_TIME_FORMS_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Zeitzettel_Template.docx");
111 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_RESULT_LIST_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Ergebnisliste_Template.docx");
112 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_RESULT_LIST_DETAIL_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\ErgebnislisteDetail_Template.docx");
113 groupDocumentCreation.MakeSureSettingExists<string>(SETTING_DOCUMENT_CREATION_ANALYTICS_TEMPLATE_PATH, @$"{DEFAULT_TEMPLATE_FOLDER_NAME}\Analyse_Template.docx");
114
115 //... Add new settings and groups here ...
116
118 }
119
120 #endregion
121
122 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123
124 #region Properties
125
129 public List<WorkspaceSettingsGroup> Groups { get; set; } = new List<WorkspaceSettingsGroup>();
130
134 public bool HasChanged => Groups.Any(g => g.HasChanged);
135
136 #endregion
137
138 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
139
140 #region Group management methods
141
148 {
149 if (Groups.Where(g => string.Compare(g.GroupKey, group.GroupKey, true) == 0).Any())
150 {
151 // A group with the same key already exists
152 throw new ArgumentException($"A group with the key '{group.GroupKey}' already exists.", nameof(group));
153 }
154 else
155 {
156 Groups.Add(group);
157 group.PropertyChanged += (sender, e) =>
158 {
159 switch (e.PropertyName)
160 {
161 case nameof(WorkspaceSettingsGroup.HasChanged): OnPropertyChanged(nameof(HasChanged)); break;
162 default: break;
163 }
164 };
165 }
166 }
167
174 public WorkspaceSettingsGroup GetGroup(string groupKey, bool createGroupIfNotExisting = false)
175 {
176 WorkspaceSettingsGroup group = Groups.FirstOrDefault(g => string.Compare(g.GroupKey, groupKey, true) == 0);
177 if (group == null && createGroupIfNotExisting)
178 {
179 group = new WorkspaceSettingsGroup(groupKey);
180 AddGroup(group);
181 }
182 return group;
183 }
184
185 #endregion
186
187 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
188
189 #region Setting Getter
190
197 public IWorkspaceSetting GetSetting(string groupKey, string settingKey)
198 {
199 WorkspaceSettingsGroup group = GetGroup(groupKey);
200 if (group != null)
201 {
202 IWorkspaceSetting setting = group.GetSetting(settingKey);
203 return setting;
204 }
205 return null;
206 }
207
215 public WorkspaceSetting<T> GetSetting<T>(string groupKey, string settingKey)
216 {
217 WorkspaceSettingsGroup group = GetGroup(groupKey);
218 if (group != null)
219 {
220 WorkspaceSetting<T> setting = group.GetSetting<T>(settingKey);
221 return setting;
222 }
223 return null;
224 }
225
233 public T GetSettingValue<T>(string groupKey, string settingKey)
234 {
235 WorkspaceSetting<T> setting = GetSetting<T>(groupKey, settingKey);
236 return setting == null ? default : setting.Value;
237 }
238
239 #endregion
240
241 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
242
243 #region Reset / Snapshot
244
248 public void ResetAll()
249 {
250 foreach (WorkspaceSettingsGroup group in Groups)
251 {
252 foreach (IWorkspaceSetting setting in group.Settings)
253 {
254 setting.Reset();
255 }
256 }
257 }
258
262 public void CreateSnapshot()
263 {
264 foreach (WorkspaceSettingsGroup group in Groups)
265 {
266 foreach (IWorkspaceSetting setting in group.Settings)
267 {
268 setting.CreateSnapshot();
269 }
270 }
271 }
272
273 #endregion
274
275 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
276
277 #region Constructors
278
284 {
286 }
287
293 {
294 Groups = new List<WorkspaceSettingsGroup>();
295 if(other == null) { return; }
296 foreach (WorkspaceSettingsGroup group in other?.Groups)
297 {
298 if (group is ICloneable cloneableGroup)
299 {
300 AddGroup((WorkspaceSettingsGroup)cloneableGroup.Clone());
301 }
302 else
303 {
304 AddGroup(group); // This assumes the group is immutable or does not require cloning
305 }
306 }
308 }
309
310 #endregion
311
312 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
313
314 #region Save / Load
315
322 public void Save(IFileService fileService, string filePath)
323 {
325 List<SerializableWorkspaceSettingsGroup> serializableGroups = Groups.Select(group => new SerializableWorkspaceSettingsGroup
326 {
327 GroupKey = group.GroupKey,
328 Settings = group.Settings.Select(s => new SerializableWorkspaceSetting
329 {
330 Key = s.Key,
331 Value = s.UntypedValue
332 }).ToList()
333 }).ToList();
334
335 fileService.Save(Path.GetDirectoryName(filePath), Path.GetFileName(filePath), serializableGroups);
336 }
337
345 public void Load(IFileService fileService, string filePath)
346 {
347 List<SerializableWorkspaceSettingsGroup> serializableGroups = fileService.Read<List<SerializableWorkspaceSettingsGroup>>(Path.GetDirectoryName(filePath), Path.GetFileName(filePath));
348 Groups.Clear();
350 if (serializableGroups != null)
351 {
352 foreach (SerializableWorkspaceSettingsGroup serializableGroup in serializableGroups)
353 {
354 foreach (SerializableWorkspaceSetting serializableSetting in serializableGroup.Settings)
355 {
356 IWorkspaceSetting setting = GetSetting(serializableGroup.GroupKey, serializableSetting.Key);
357 if (setting != null)
358 {
359 object serializableValue = serializableSetting.Value;
360 if(serializableValue is string strValue && setting.ValueType.IsEnum)
361 {
362 serializableValue = Enum.Parse(setting.ValueType, strValue);
363 }
364 setting.UntypedValue = serializableValue;
365 }
366 }
367 }
368 }
370 }
371
372 #endregion
373
374 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
375
376 #region IEquatable, ICloneable
377
378 public override bool Equals(object obj)
379 => obj is WorkspaceSettings s && s.Groups.SequenceEqual(Groups);
380
381 public bool Equals(WorkspaceSettings other)
382 => Equals((object)other);
383
384 public override int GetHashCode()
385 => Groups.GetHashCode();
386
387 public object Clone()
388 => new WorkspaceSettings(this);
389
390 #endregion
391 }
392}
Class describing the properties of the WorkspaceSetting<T> that should be saved to a file.
Class describing the properties of the WorkspaceSettingsGroup that should be saved to a file.
List< SerializableWorkspaceSetting > Settings
List with SerializableWorkspaceSetting instances belonging to this group.
List< IWorkspaceSetting > Settings
List with IWorkspaceSetting instances belonging to this group.
bool HasChanged
Indicating if any of the Settings has changed.
IWorkspaceSetting GetSetting(string settingKey)
Get the setting with the requested key.
void Save(IFileService fileService, string filePath)
Save this instance to a file using the IFileService.
const string DEFAULT_TEMPLATE_FOLDER_NAME
Folder name where the document templates are located per default (e.g.
WorkspaceSettingsGroup GetGroup(string groupKey, bool createGroupIfNotExisting=false)
Get the WorkspaceSettingsGroup with the requested key.
void AddGroup(WorkspaceSettingsGroup group)
Add a new WorkspaceSettingsGroup
WorkspaceSettings(WorkspaceSettings other)
Copy Constructor.
void initializeSettings()
Make sure that all necessary groups and settings are available and create them is not existing.
T GetSettingValue< T >(string groupKey, string settingKey)
Get the WorkspaceSetting<T>.Value by the requested keys.
WorkspaceSettings()
Parameterless Constructor Initialize all settings.
void Load(IFileService fileService, string filePath)
Load the settings from a file using the IFileService The SerializableWorkspaceSetting and Serializabl...
void ResetAll()
Reset all IWorkspaceSetting instances in all WorkspaceSettingsGroup instances.
List< WorkspaceSettingsGroup > Groups
List with WorkspaceSettingsGroup instances.
bool HasChanged
Indicating if any of the Groups has changed.
IWorkspaceSetting GetSetting(string groupKey, string settingKey)
Get the IWorkspaceSetting by the requested keys.
WorkspaceSetting< T > GetSetting< T >(string groupKey, string settingKey)
Get the WorkspaceSetting<T> by the requested keys.
void CreateSnapshot()
Create a snapshot of all IWorkspaceSetting instances in all WorkspaceSettingsGroup instances.
Interface for a service that handles file operations.
Interface for a single workspace setting.
void Reset()
Set the UntypedValue to the UntypedSnapshotValue
void CreateSnapshot()
Save the UntypedValue to the UntypedSnapshotValue
CompetitionSearchModes
Different types of modes to search for the matching competition.
DocumentCreationFileTypes
Different file types of documents that can be created.