Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DesignModel.cs
10using Microsoft.Win32;
11using System;
12using System.Collections.Generic;
13using System.IO;
14using System.Text;
15using System.Threading.Tasks;
16using System.Windows;
17using System.Windows.Controls;
18using System.Windows.Data;
19using System.Windows.Input;
20using System.Windows.Markup;
21using System.Windows.Media;
22using System.Xml;
23using TAG.Content.Microsoft;
24using Waher.Content;
26using Waher.Events;
33using Waher.Script;
34
36{
40 [Singleton]
42 {
43 private const string defaultParameterDescription = "Enter parameter description as **Markdown**";
44 private const string defaultParameterLabel = "Enter label as **Markdown**";
45
46 private readonly Property<Waher.Content.Duration?> archiveOptional;
47 private readonly Property<Waher.Content.Duration?> archiveRequired;
48 private readonly Property<Waher.Content.Duration?> duration;
49 private readonly Property<ContractVisibility> visibility;
50 private readonly Property<ContractParts> partsMode;
51 private readonly Property<string> language;
52 private readonly Property<Iso__639_1.Record[]> languages;
53 private readonly Property<DateTime?> signBefore;
54 private readonly Property<DateTime?> signAfter;
55 private readonly Property<string> contractId;
56 private readonly Property<bool> parametersOk;
57 private readonly Property<RoleInfo[]> roles;
58 private readonly Property<PartInfo[]> parts;
59 private readonly Property<ParameterInfo[]> parameters;
60 private readonly Property<RoleReferenceParameterInfo[]> roleReferenceParameters;
61 private readonly Property<ContractReferenceParameterInfo[]> contractReferenceParameters;
62 private readonly DelayedActionProperty<string> machineReadable;
63 private readonly Property<string> forMachinesLocalName;
64 private readonly Property<string> forMachinesNamespace;
65 private readonly Property<XmlElement> forMachines;
66 private readonly DelayedActionProperty<string> humanReadableMarkdown;
67 private readonly Property<object> humanReadable;
68 private readonly PersistedProperty<string> openAiKey;
69
70 private readonly Command addRole;
71 private readonly Command addPart;
72 private readonly Command addNumericParameter;
73 private readonly Command addStringParameter;
74 private readonly Command addBooleanParameter;
75 private readonly Command addDateParameter;
76 private readonly Command addDateTimeParameter;
77 private readonly Command addTimeParameter;
78 private readonly Command addDurationParameter;
79 private readonly Command addCalcParameter;
80 private readonly Command addRoleReference;
81 private readonly Command addContractReference;
82 private readonly Command @new;
83 private readonly Command load;
84 private readonly Command import;
85 private readonly Command save;
86 private readonly Command propose;
87 private readonly Command addLanguage;
88 private readonly Command removeLanguage;
89
90 private Contract contract;
91 private string lastLanguage = string.Empty;
92
96 public DesignModel()
97 {
98 this.visibility = new Property<ContractVisibility>(nameof(this.Visibility), ContractVisibility.Public, this);
99 this.partsMode = new Property<ContractParts>(nameof(this.PartsMode), ContractParts.TemplateOnly, this);
100 this.archiveOptional = new Property<Waher.Content.Duration?>(nameof(this.ArchiveOptional), Waher.Content.Duration.Zero, this);
101 this.archiveRequired = new Property<Waher.Content.Duration?>(nameof(this.ArchiveRequired), Waher.Content.Duration.Zero, this);
102 this.duration = new Property<Waher.Content.Duration?>(nameof(this.Duration), Waher.Content.Duration.Zero, this);
103 this.language = new Property<string>(nameof(this.Language), "en", this);
104 this.languages = new Property<Iso__639_1.Record[]>(nameof(this.Languages), Array.Empty<Iso__639_1.Record>(), this);
105 this.signBefore = new Property<DateTime?>(nameof(this.SignBefore), null, this);
106 this.signAfter = new Property<DateTime?>(nameof(this.SignAfter), null, this);
107 this.parametersOk = new Property<bool>(nameof(this.ParametersOk), false, this);
108 this.roles = new Property<RoleInfo[]>(nameof(this.Roles), Array.Empty<RoleInfo>(), this);
109 this.parts = new Property<PartInfo[]>(nameof(this.Parts), Array.Empty<PartInfo>(), this);
110 this.parameters = new Property<ParameterInfo[]>(nameof(this.Parameters), Array.Empty<ParameterInfo>(), this);
111 this.roleReferenceParameters = new Property<RoleReferenceParameterInfo[]>(nameof(this.RoleReferenceParameters), Array.Empty<RoleReferenceParameterInfo>(), this);
112 this.contractReferenceParameters = new Property<ContractReferenceParameterInfo[]>(nameof(this.ContractReferenceParameters), Array.Empty<ContractReferenceParameterInfo>(), this);
113 this.machineReadable = new DelayedActionProperty<string>(nameof(this.MachineReadable), TimeSpan.FromSeconds(1), string.Empty, this);
114 this.forMachines = new Property<XmlElement>(nameof(this.ForMachines), null, this);
115 this.forMachinesLocalName = new Property<string>(nameof(this.ForMachinesLocalName), string.Empty, this);
116 this.forMachinesNamespace = new Property<string>(nameof(this.ForMachinesNamespace), string.Empty, this);
117 this.contractId = new Property<string>(nameof(this.ContractId), string.Empty, this);
118 this.humanReadableMarkdown = new DelayedActionProperty<string>(nameof(this.HumanReadableMarkdown), TimeSpan.FromSeconds(1), true, string.Empty, this);
119 this.humanReadable = new Property<object>(nameof(this.HumanReadable), null, this);
120
121 this.roles.PropertyChanged += this.Roles_PropertyChanged;
122 this.parameters.PropertyChanged += this.Parameters_PropertyChanged;
123 this.roleReferenceParameters.PropertyChanged += this.Parameters_PropertyChanged;
124 this.contractReferenceParameters.PropertyChanged += this.Parameters_PropertyChanged;
125 this.parts.PropertyChanged += this.Parts_PropertyChanged;
126
127 this.Add(this.openAiKey = new PersistedProperty<string>("Design", nameof(this.OpenAiKey), true, string.Empty, this));
128
129 this.machineReadable.OnAction += this.NormalizeMachineReadableXml;
130 this.humanReadableMarkdown.OnAction += this.RenderHumanReadableMarkdown;
131
132 this.addRole = new Command(this.ExecuteAddRole);
133 this.addPart = new Command(this.ExecuteAddPart);
134 this.addNumericParameter = new Command(this.ExecuteAddNumericParameter);
135 this.addStringParameter = new Command(this.ExecuteAddStringParameter);
136 this.addBooleanParameter = new Command(this.ExecuteAddBooleanParameter);
137 this.addDateParameter = new Command(this.ExecuteAddDateParameter);
138 this.addDateTimeParameter = new Command(this.ExecuteAddDateTimeParameter);
139 this.addTimeParameter = new Command(this.ExecuteAddTimeParameter);
140 this.addDurationParameter = new Command(this.ExecuteAddDurationParameter);
141 this.addCalcParameter = new Command(this.ExecuteAddCalcParameter);
142 this.addRoleReference = new Command(this.ExecuteAddRoleReference);
143 this.addContractReference = new Command(this.ExecuteAddContractReference);
144 this.@new = new Command(this.ExecuteNewContract);
145 this.load = new Command(this.ExecuteLoadContract);
146 this.import = new Command(this.ExecuteImportContract);
147 this.save = new Command(this.ExecuteSaveContract);
148 this.propose = new Command(this.CanExecuteProposeContract, this.ExecuteProposeContract);
149 this.addLanguage = new Command(this.ExecuteAddLanguage);
150 this.removeLanguage = new Command(this.CanExecuteRemoveLanguage, this.ExecuteRemoveLanguage);
151
152 this.GenerateContract().Wait();
153 }
154
155 private async Task GenerateContract()
156 {
157 await this.SetContract(new Contract()
158 {
161 Attachments = Array.Empty<Attachment>(),
162 CanActAsTemplate = true,
163 ClientSignatures = Array.Empty<ClientSignature>(),
164 ContractId = this.ContractId,
165 Duration = this.Duration,
166 ForHumans = Array.Empty<HumanReadableText>(),
168 Parameters = Array.Empty<Parameter>(),
169 Parts = Array.Empty<Part>(),
170 PartsMode = ContractParts.TemplateOnly,
171 Roles = Array.Empty<Role>(),
172 ServerSignature = null,
173 SignAfter = this.SignAfter,
174 SignBefore = this.SignBefore,
175 TemplateId = string.Empty,
176 Visibility = ContractVisibility.PublicSearchable
177 });
178 }
179
180 public async Task SetContract(Contract Contract)
181 {
182 if (this.contract is not null)
183 this.contract.FormatParameterDisplay -= this.Contract_FormatParameterDisplay;
184
185 this.contract = Contract;
186 this.contract.FormatParameterDisplay += this.Contract_FormatParameterDisplay;
187
188 this.ContractId = Contract.ContractId;
189 this.ArchiveOptional = Contract.ArchiveOptional;
190 this.ArchiveRequired = Contract.ArchiveRequired;
191 this.Duration = Contract.Duration;
192 this.SignBefore = Contract.SignBefore;
193 this.SignAfter = Contract.SignAfter;
194 this.Visibility = Contract.Visibility;
195 this.PartsMode = Contract.PartsMode;
196
197 List<PartInfo> Parts = new();
198
199 if (Contract.Parts is not null)
200 {
201 foreach (Part Part in Contract.Parts)
202 Parts.Add(new PartInfo(Part, this, this.parts));
203 }
204
205 this.Parts = Parts.ToArray();
206
207 List<RoleInfo> Roles = new();
208
209 if (Contract.Roles is not null)
210 {
211 foreach (Role Role in Contract.Roles)
212 Roles.Add(new RoleInfo(this, Role, this.roles));
213 }
214
215 this.Roles = Roles.ToArray();
216
217 List<ParameterInfo> ParameterList = new();
218 List<RoleReferenceParameterInfo> RoleReferenceParameterList = new();
219 List<ContractReferenceParameterInfo> ContractReferenceParameterList = new();
221
222 foreach (Parameter Parameter in this.contract.Parameters)
223 {
224 if (Parameter is BooleanParameter BP)
225 ParameterInfo = this.GetParameterInfo(BP);
226 else if (Parameter is NumericalParameter NP)
227 ParameterInfo = this.GetParameterInfo(NP);
228 else if (Parameter is StringParameter SP)
229 ParameterInfo = this.GetParameterInfo(SP);
230 else if (Parameter is DateParameter DP)
231 ParameterInfo = this.GetParameterInfo(DP);
232 else if (Parameter is DateTimeParameter DTP)
233 ParameterInfo = this.GetParameterInfo(DTP);
234 else if (Parameter is TimeParameter TP)
235 ParameterInfo = this.GetParameterInfo(TP);
236 else if (Parameter is DurationParameter DrP)
237 ParameterInfo = this.GetParameterInfo(DrP);
238 else if (Parameter is CalcParameter CP)
239 ParameterInfo = this.GetParameterInfo(CP);
240 else if (Parameter is RoleParameter RP)
241 {
242 RoleReferenceParameterList.Add(this.GetParameterInfo(RP));
243 continue;
244 }
246 {
247 ContractReferenceParameterList.Add(this.GetParameterInfo(CRP));
248 continue;
249 }
250 else
251 continue;
252
253 ParameterList.Add(ParameterInfo);
254 }
255
256 this.Parameters = ParameterList.ToArray();
257 this.RoleReferenceParameters = RoleReferenceParameterList.ToArray();
258 this.ContractReferenceParameters = ContractReferenceParameterList.ToArray();
259
260 await this.ValidateParameters();
261
262 (string s, XmlElement E) = Contract.ForMachines.ToPrettyXml();
263
264 this.MachineReadable = s.Replace("\n\t", "\n");
265 this.ForMachines = E;
266
267 this.Languages = Contract.GetLanguages().ToIso639_1();
268 this.Language = Contract.DefaultLanguage;
269
270 if (string.IsNullOrEmpty(this.Language) && this.Languages.Length == 0)
271 {
272 this.Languages = new string[] { "en" }.ToIso639_1();
273 this.Language = "en";
274 }
275
276 this.HumanReadableMarkdown = (await Contract.ToMarkdown(this.Language, MarkdownType.ForEditing))?.Trim() ?? string.Empty;
277 }
278
279 private Task Contract_FormatParameterDisplay(object Sender, ParameterValueFormattingEventArgs e)
280 {
281 if (e.Value is Waher.Content.Duration D)
282 e.Value = DurationToString.ToString(D);
283
284 return Task.CompletedTask;
285 }
286
290 public Contract Contract => this.contract;
291
293 public override async Task Start()
294 {
295 await base.Start();
296
297 MainWindow.currentInstance.DesignTab.DataContext = this;
298 MainWindow.currentInstance.DesignTab.OpenAiKey.Password = this.OpenAiKey;
299 }
300
305 {
306 get => this.visibility.Value;
307 set
308 {
309 this.visibility.Value = value;
310 this.contract.Visibility = value;
311 }
312 }
313
317 public static string[] Visibilities => Enum.GetNames(typeof(ContractVisibility));
318
323 {
324 get => this.partsMode.Value;
325 set
326 {
327 this.partsMode.Value = value;
328 this.contract.PartsMode = value;
329
330 this.propose.RaiseCanExecuteChanged();
331 }
332 }
333
337 public static string[] PartsModes => Enum.GetNames(typeof(ContractParts));
338
343 {
344 get => this.archiveOptional.Value;
345 set
346 {
347 this.archiveOptional.Value = value;
348 this.contract.ArchiveOptional = value;
349 }
350 }
351
356 {
357 get => this.archiveRequired.Value;
358 set
359 {
360 this.archiveRequired.Value = value;
361 this.contract.ArchiveRequired = value;
362 }
363 }
364
369 {
370 get => this.duration.Value;
371 set
372 {
373 this.duration.Value = value;
374 this.contract.Duration = value;
375 }
376 }
377
381 public string Language
382 {
383 get => this.language.Value;
384 set => this.SetLanguage(value);
385 }
386
387 private async void SetLanguage(string Language)
388 {
389 try
390 {
391 this.language.Value = Language;
392 this.removeLanguage.RaiseCanExecuteChanged();
393
394 if (this.lastLanguage != Language)
395 {
396 string FromLanguage = this.lastLanguage;
397
398 if (string.IsNullOrEmpty(FromLanguage) || string.IsNullOrEmpty(Language))
399 {
400 if (!string.IsNullOrEmpty(Language))
401 {
403
404 foreach (ParameterInfo PI in this.AllParameterInfos)
405 {
406 Text = PI.Parameter.Descriptions.Find(Language);
407
408 if (Text is null)
409 PI.DescriptionAsMarkdown = string.Empty;
410 else
411 PI.DescriptionAsMarkdown = (await Text.GenerateMarkdown(this.contract, MarkdownType.ForEditing) ?? string.Empty).Trim();
412 }
413
414 foreach (RoleInfo RI in this.Roles)
415 {
416 Text = RI.Role.Descriptions.Find(Language);
417
418 if (Text is null)
419 RI.DescriptionAsMarkdown = string.Empty;
420 else
421 RI.DescriptionAsMarkdown = (await Text.GenerateMarkdown(this.contract, MarkdownType.ForEditing) ?? string.Empty).Trim();
422 }
423
424 Text = this.contract.ForHumans.Find(Language);
425 if (Text is null)
426 this.HumanReadableMarkdown = string.Empty;
427 else
428 this.HumanReadableMarkdown = (await Text.GenerateMarkdown(this.contract, MarkdownType.ForEditing) ?? string.Empty).Trim();
429
430 this.lastLanguage = Language;
431 }
432 }
433 else
434 {
435 this.lastLanguage = Language;
436
437 List<TranslationItem> Items = new();
438
439 foreach (ParameterInfo PI in this.AllParameterInfos)
440 await Add(Items, PI, FromLanguage, Language);
441
442 foreach (RoleInfo RI in this.Roles)
443 await Add(Items, RI, FromLanguage, Language);
444
445 await Add(Items, this, FromLanguage, Language);
446
447 if (Items.Count > 0)
448 {
449 List<string> AllTexts = new();
450
451 foreach (TranslationItem Item in Items)
452 AllTexts.AddRange(Item.Original);
453
454 string[] AllTranslated = await Translator.Translate(AllTexts.ToArray(), FromLanguage, Language, this.OpenAiKey);
455
457 {
458 int i = 0;
459 int c;
460
461 foreach (TranslationItem Item in Items)
462 {
463 string[] Translated = new string[c = Item.Original.Length];
464
465 Array.Copy(AllTranslated, i, Translated, 0, c);
466 i += c;
467
468 Item.Object.SetTranslatableTexts(Translated, Language);
469 }
470
471 this.removeLanguage.RaiseCanExecuteChanged();
472
473 return Task.CompletedTask;
474 });
475 }
476 }
477
478 this.removeLanguage.RaiseCanExecuteChanged();
479 }
480 }
481 catch (Exception ex)
482 {
483 Log.Exception(ex);
484 MainWindow.ErrorBox(ex.Message);
485 }
486 }
487
488 private static async Task Add(List<TranslationItem> Items, ITranslatable Translatable, string From, string To)
489 {
490 string[] Texts = await Translatable.GetTranslatableTexts(To);
491 if (Texts is not null)
492 Translatable.SetTranslatableTexts(Texts, To);
493 else
494 {
495 Texts = await Translatable.GetTranslatableTexts(From);
496 if (Texts is not null)
497 {
498 Items.Add(new TranslationItem()
499 {
500 Object = Translatable,
501 Original = Texts
502 });
503 }
504 }
505 }
506
507 private class TranslationItem
508 {
509 public ITranslatable Object;
510 public string[] Original;
511 }
512
518 public async Task<string[]> GetTranslatableTexts(string Language)
519 {
520 HumanReadableText Text = this.contract.ForHumans.Find(Language);
521 if (Text is null)
522 return null;
523 else
524 return new string[] { await Text.GenerateMarkdown(this.Contract, MarkdownType.ForEditing) };
525 }
526
532 public void SetTranslatableTexts(string[] Texts, string Language)
533 {
534 if (Texts.Length > 0)
535 this.HumanReadableMarkdown = Texts[0].Trim();
536 }
537
542 {
543 get => this.languages.Value;
544 set
545 {
546 this.languages.Value = value;
547 this.removeLanguage.RaiseCanExecuteChanged();
548 }
549 }
550
554 public DateTime? SignBefore
555 {
556 get => this.signBefore.Value;
557 set
558 {
559 this.signBefore.Value = value;
560 this.contract.SignBefore = value;
561 }
562 }
563
567 public DateTime? SignAfter
568 {
569 get => this.signAfter.Value;
570 set
571 {
572 this.signAfter.Value = value;
573 this.contract.SignAfter = value;
574 }
575 }
576
580 public bool ParametersOk
581 {
582 get => this.parametersOk.Value;
583 set
584 {
585 this.parametersOk.Value = value;
586 this.propose.RaiseCanExecuteChanged();
587 }
588 }
589
593 public string MachineReadable
594 {
595 get => this.machineReadable.Value;
596 set => this.machineReadable.Value = value;
597 }
598
599 private void NormalizeMachineReadableXml(object sender, EventArgs e)
600 {
602 {
603 try
604 {
605 this.contract.ForMachines = this.machineReadable.Value.NormalizeXml();
606 this.ForMachines = this.contract.ForMachines;
607 }
608 catch (Exception ex)
609 {
610 this.contract.ForMachines = null;
611 Log.Exception(ex);
612 }
613
614 this.propose.RaiseCanExecuteChanged();
615
616 return Task.CompletedTask;
617 });
618 }
619
623 public XmlElement ForMachines
624 {
625 get => this.forMachines.Value;
626 set
627 {
628 this.forMachines.Value = value;
629 this.forMachinesLocalName.Value = value?.LocalName;
630 this.forMachinesNamespace.Value = value?.NamespaceURI;
631 }
632 }
633
638 {
639 get => this.forMachinesLocalName.Value;
640 }
641
646 {
647 get => this.forMachinesNamespace.Value;
648 }
649
653 public string ContractId
654 {
655 get => this.contractId.Value;
656 set
657 {
658 this.contractId.Value = value;
659 this.contract.ContractId = value;
660
661 this.propose.RaiseCanExecuteChanged();
662 }
663 }
664
669 {
670 get => this.humanReadableMarkdown.Value;
671 set => this.humanReadableMarkdown.Value = value;
672 }
673
677 public object HumanReadable
678 {
679 get => this.humanReadable.Value;
680 set => this.humanReadable.Value = value;
681 }
682
683 private void RenderHumanReadableMarkdown(object sender, EventArgs e)
684 {
685 MainWindow.UpdateGui(async () =>
686 {
687 try
688 {
689 HumanReadableText Text = await this.HumanReadableMarkdown.ToHumanReadableText(this.Language);
690 if (Text is null)
691 {
692 this.contract.ForHumans = this.contract.ForHumans.Remove(this.Language);
693 this.HumanReadable = null;
694 }
695 else
696 {
697 this.contract.ForHumans = this.contract.ForHumans.Append(Text);
698 string Xaml = await Text.GenerateXAML(this.Contract);
699 this.HumanReadable = XamlReader.Parse(Xaml);
700 }
701 }
702 catch (Exception ex)
703 {
704 Log.Exception(ex);
705 }
706 });
707 }
708
712 public async Task ValidateParameters()
713 {
714 Variables Variables = new();
715 bool Ok = true;
716
717 Variables["Duration"] = this.Duration;
718
719 foreach (ParameterInfo P in this.AllParameterInfos)
721
722 foreach (ParameterInfo P in this.AllParameterInfos)
723 {
724 if (await P.ValidateParameter(Variables))
725 P.Control.Background = P.Protection.DefaultBrush();
726 else
727 {
728 P.Control.Background = Brushes.Salmon;
729 Ok = false;
730 }
731 }
732
733 this.ParametersOk = Ok;
734 }
735
740 {
741 get => this.roles.Value;
742 set => this.roles.Value = value;
743 }
744
748 public string[] RoleNames
749 {
750 get
751 {
752 RoleInfo[] Roles = this.Roles;
753
754 if (Roles is null)
755 return Array.Empty<string>();
756
757 int i, c = Roles.Length;
758 string[] Result = new string[c];
759
760 for (i = 0; i < c; i++)
761 Result[i] = Roles[i].Name;
762
763 return Result;
764 }
765 }
766
773 public bool TryGetRole(string Name, out RoleInfo Role)
774 {
775 Role = null;
776
777 if (this.roles?.Value is null)
778 return false;
779
780 foreach (RoleInfo R in this.roles.Value)
781 {
782 if (R.Name == Name)
783 {
784 Role = R;
785 return true;
786 }
787 }
788
789 return false;
790 }
791
792 private void Roles_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
793 {
794 this.contract.Roles = this.roles.Value.ToRoles();
795 }
796
801 {
802 get => this.parts.Value;
803 set => this.parts.Value = value;
804 }
805
806 private void Parts_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
807 {
808 this.contract.Parts = this.parts.Value.ToParts();
809 }
810
815 {
816 get => this.parameters.Value;
817 set => this.parameters.Value = value;
818 }
819
824 {
825 get => this.roleReferenceParameters.Value;
826 set => this.roleReferenceParameters.Value = value;
827 }
828
833 {
834 get => this.contractReferenceParameters.Value;
835 set => this.contractReferenceParameters.Value = value;
836 }
837
842 {
843 get
844 {
845 List<ParameterInfo> Parameters = new();
846
847 Parameters.AddRange(this.contractReferenceParameters.Value);
848 Parameters.AddRange(this.parameters.Value);
849 Parameters.AddRange(this.roleReferenceParameters.Value);
850
851 return Parameters.ToArray();
852 }
853 }
854
859 {
860 get
861 {
862 List<Parameter> Parameters = new();
863
864 Parameters.AddRange(this.contractReferenceParameters.Value.ToParameters());
865 Parameters.AddRange(this.parameters.Value.ToParameters());
866 Parameters.AddRange(this.roleReferenceParameters.Value.ToParameters());
867
868 return Parameters.ToArray();
869 }
870 }
871
872 private void Parameters_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
873 {
874 this.contract.Parameters = this.AllParameters;
875 }
876
880 public ICommand AddRole => this.addRole;
881
885 public async Task ExecuteAddRole()
886 {
887 RoleInfo[] Roles = this.Roles;
888 int c = Roles.Length;
889
890 Array.Resize(ref Roles, c + 1);
891 Roles[c] = new RoleInfo(this, new Role()
892 {
893 Name = FindNewName("Role", this.Roles),
894 Descriptions = new HumanReadableText[] { await "Enter role description as **Markdown**".ToHumanReadableText("en") },
895 MinCount = 1,
896 MaxCount = 1,
897 CanRevoke = false
898 }, this.roles);
899
900 this.Roles = Roles;
901
902 foreach (ParameterInfo RoleRef in this.roleReferenceParameters.Value)
903 {
904 if (RoleRef is RoleReferenceParameterInfo RoleRefInfo)
905 RoleRefInfo.RaisePropertyChanged(nameof(RoleRefInfo.Roles));
906 }
907 }
908
909 private static string FindNewName(string ProposedName, INamedItem[] NamedItems)
910 {
911 int i = 1;
912 string Result;
913
914 while (true)
915 {
916 string Suffix = i.ToString();
917 bool Found = false;
918
919 Result = ProposedName + Suffix;
920
921 foreach (INamedItem Item in NamedItems)
922 {
923 if (Item.Name == Result)
924 {
925 Found = true;
926 break;
927 }
928 }
929
930 if (Found)
931 i++;
932 else
933 return Result;
934 }
935 }
936
942 {
943 RoleInfo[] Roles = this.Roles;
944 int i = Array.IndexOf(Roles, Role);
945 if (i < 0)
946 return;
947
948 int c = Roles.Length;
949
950 if (i < c - 1)
951 Array.Copy(Roles, i + 1, Roles, i, c - i - 1);
952
953 Array.Resize(ref Roles, c - 1);
954
955 this.Roles = Roles;
956 }
957
961 public ICommand AddPart => this.addPart;
962
966 public Task ExecuteAddPart()
967 {
968 PartInfo[] Parts = this.Parts;
969 int c = Parts.Length;
970
971 Array.Resize(ref Parts, c + 1);
972 Parts[c] = new PartInfo(new Part()
973 {
974 LegalId = string.Empty,
975 Role = string.Empty
976 }, this, this.parts);
977
978 this.Parts = Parts;
979 this.PartsMode = ContractParts.ExplicitlyDefined;
980
981 return Task.CompletedTask;
982 }
983
989 {
990 PartInfo[] Parts = this.Parts;
991 int i = Array.IndexOf(Parts, Part);
992 if (i < 0)
993 return;
994
995 int c = Parts.Length;
996
997 if (i < c - 1)
998 Array.Copy(Parts, i + 1, Parts, i, c - i - 1);
999
1000 Array.Resize(ref Parts, c - 1);
1001
1002 this.Parts = Parts;
1003 }
1004
1008 public ICommand AddNumericParameter => this.addNumericParameter;
1009
1014 {
1015 return this.ExecuteAddNumericParameter("Numeric", null, defaultParameterDescription);
1016 }
1017
1018 private async Task ExecuteAddNumericParameter(string Name, decimal? Value, params string[] MarkdownDescription)
1019 {
1020 NumericalParameter NP = new()
1021 {
1022 Name = FindNewName(Name, this.AllParameterInfos),
1023 Descriptions = await MarkdownDescription.ToHumanReadableText("en"),
1024 Expression = string.Empty,
1025 Guide = string.Empty,
1026 Max = null,
1027 MaxIncluded = false,
1028 Min = null,
1029 MinIncluded = false,
1030 Value = Value,
1031 Protection = ProtectionLevel.Normal
1032 };
1033
1034 this.AddParameter(this.GetParameterInfo(NP));
1035 }
1036
1037 private ParameterInfo GetParameterInfo(NumericalParameter NP)
1038 {
1039 TextBox ValueControl = new();
1040 Binding Binding = new("Value")
1041 {
1042 Converter = new MoneyToString()
1043 };
1044 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1045 ValueControl.SetBinding(TextBox.TextProperty, "Value");
1046 ValueControl.TextChanged += this.Parameter_TextChanged;
1047
1048 TextBox MinControl = new();
1049 Binding = new("Value")
1050 {
1051 Converter = new MoneyToString()
1052 };
1053 MinControl.SetBinding(TextBox.TextProperty, Binding);
1054 MinControl.SetBinding(TextBox.TextProperty, "Min");
1055 MinControl.TextChanged += this.Parameter_MinTextChanged;
1056
1057 TextBox MaxControl = new();
1058 Binding = new Binding("Value")
1059 {
1060 Converter = new MoneyToString()
1061 };
1062 MaxControl.SetBinding(TextBox.TextProperty, Binding);
1063 MaxControl.SetBinding(TextBox.TextProperty, "Max");
1064 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1065
1066 CheckBox MinIncludedControl = new();
1067 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1068 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1069 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1070
1071 CheckBox MaxIncludedControl = new();
1072 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1073 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1074 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1075
1076 ParameterInfo ParameterInfo = new NumericalParameterInfo(this.contract, NP, ValueControl, MinControl, MinIncludedControl,
1077 MaxControl, MaxIncludedControl, this, this.parameters);
1078 ValueControl.Tag = ParameterInfo;
1079 MinControl.Tag = ParameterInfo;
1080 MaxControl.Tag = ParameterInfo;
1081 MinIncludedControl.Tag = ParameterInfo;
1082 MaxIncludedControl.Tag = ParameterInfo;
1083
1084 return ParameterInfo;
1085 }
1086
1090 public ICommand AddStringParameter => this.addStringParameter;
1091
1096 {
1097 return this.ExecuteAddStringParameter("String", null, null, defaultParameterDescription);
1098 }
1099
1100 private async Task ExecuteAddStringParameter(string Name, string RegEx, int? MaxLength, params string[] MarkdownDescription)
1101 {
1102 StringParameter SP = new()
1103 {
1104 Name = FindNewName(Name, this.AllParameterInfos),
1105 Descriptions = await MarkdownDescription.ToHumanReadableText("en"),
1106 Expression = string.Empty,
1107 Guide = string.Empty,
1108 Max = null,
1109 MaxIncluded = false,
1110 Min = null,
1111 MinIncluded = false,
1112 Value = null,
1113 MinLength = null,
1114 MaxLength = MaxLength,
1115 RegEx = RegEx,
1116 Protection = ProtectionLevel.Normal
1117 };
1118
1119 this.AddParameter(this.GetParameterInfo(SP));
1120 }
1121
1122 private ParameterInfo GetParameterInfo(StringParameter SP)
1123 {
1124 TextBox ValueControl = new();
1125 ValueControl.SetBinding(TextBox.TextProperty, "Value");
1126 ValueControl.TextChanged += this.Parameter_TextChanged;
1127
1128 TextBox MinControl = new();
1129 MinControl.SetBinding(TextBox.TextProperty, "Min");
1130 MinControl.TextChanged += this.Parameter_MinTextChanged;
1131
1132 TextBox MaxControl = new();
1133 MaxControl.SetBinding(TextBox.TextProperty, "Max");
1134 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1135
1136 CheckBox MinIncludedControl = new();
1137 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1138 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1139 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1140
1141 CheckBox MaxIncludedControl = new();
1142 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1143 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1144 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1145
1146 TextBox MinLengthControl = new();
1147 MinLengthControl.SetBinding(TextBox.TextProperty, "MinLength");
1148 MinLengthControl.TextChanged += this.Parameter_MinLengthTextChanged;
1149
1150 TextBox MaxLengthControl = new();
1151 MaxLengthControl.SetBinding(TextBox.TextProperty, "MaxLength");
1152 MaxLengthControl.TextChanged += this.Parameter_MaxLengthTextChanged;
1153
1154 TextBox RegExControl = new();
1155 RegExControl.SetBinding(TextBox.TextProperty, "RegEx");
1156 RegExControl.TextChanged += this.Parameter_RegExTextChanged;
1157
1158 ParameterInfo ParameterInfo = new StringParameterInfo(this.contract, SP, ValueControl, MinControl, MinIncludedControl,
1159 MaxControl, MaxIncludedControl, MinLengthControl, MaxLengthControl, RegExControl, this, this.parameters);
1160
1161 ValueControl.Tag = ParameterInfo;
1162 MinControl.Tag = ParameterInfo;
1163 MaxControl.Tag = ParameterInfo;
1164 MinIncludedControl.Tag = ParameterInfo;
1165 MaxIncludedControl.Tag = ParameterInfo;
1166
1167 return ParameterInfo;
1168 }
1169
1170 private async void Parameter_TextChanged(object sender, RoutedEventArgs e)
1171 {
1172 try
1173 {
1174 if (sender is not TextBox TextBox || TextBox.Tag is not ParameterInfo ParameterInfo)
1175 return;
1176
1177 try
1178 {
1179 ParameterInfo.SetValue(TextBox.Text);
1180
1181 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1182 await this.ValidateParameters();
1183 }
1184 catch (Exception)
1185 {
1186 TextBox.Background = Brushes.Salmon;
1187 }
1188
1189 this.RenderHumanReadableMarkdown(this, EventArgs.Empty);
1190 }
1191 catch (Exception ex)
1192 {
1193 Log.Exception(ex);
1194 }
1195 }
1196
1197 private async void Parameter_MinTextChanged(object sender, RoutedEventArgs e)
1198 {
1199 try
1200 {
1201 if (sender is not TextBox TextBox || TextBox.Tag is not RangedParameterInfo ParameterInfo)
1202 return;
1203
1204 try
1205 {
1206 ParameterInfo.SetMin(TextBox.Text);
1207
1208 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1209 await this.ValidateParameters();
1210 }
1211 catch (Exception)
1212 {
1213 TextBox.Background = Brushes.Salmon;
1214 }
1215 }
1216 catch (Exception ex)
1217 {
1218 Log.Exception(ex);
1219 }
1220 }
1221
1222 private async void Parameter_MaxTextChanged(object sender, RoutedEventArgs e)
1223 {
1224 try
1225 {
1226 if (sender is not TextBox TextBox || TextBox.Tag is not RangedParameterInfo ParameterInfo)
1227 return;
1228
1229 try
1230 {
1231 ParameterInfo.SetMax(TextBox.Text);
1232
1233 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1234 await this.ValidateParameters();
1235 }
1236 catch (Exception)
1237 {
1238 TextBox.Background = Brushes.Salmon;
1239 }
1240 }
1241 catch (Exception ex)
1242 {
1243 Log.Exception(ex);
1244 }
1245 }
1246
1247 private async void Parameter_MinLengthTextChanged(object sender, RoutedEventArgs e)
1248 {
1249 try
1250 {
1251 if (sender is not TextBox TextBox || TextBox.Tag is not StringParameterInfo ParameterInfo)
1252 return;
1253
1254 try
1255 {
1256 string Value = TextBox.Text;
1257
1258 if (string.IsNullOrEmpty(Value))
1259 ParameterInfo.MinLength = null;
1260 else
1261 ParameterInfo.MinLength = int.Parse(Value);
1262
1263 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1264 await this.ValidateParameters();
1265 }
1266 catch (Exception)
1267 {
1268 TextBox.Background = Brushes.Salmon;
1269 }
1270 }
1271 catch (Exception ex)
1272 {
1273 Log.Exception(ex);
1274 }
1275 }
1276
1277 private async void Parameter_MaxLengthTextChanged(object sender, RoutedEventArgs e)
1278 {
1279 try
1280 {
1281 if (sender is not TextBox TextBox || TextBox.Tag is not StringParameterInfo ParameterInfo)
1282 return;
1283
1284 try
1285 {
1286 string Value = TextBox.Text;
1287
1288 if (string.IsNullOrEmpty(Value))
1289 ParameterInfo.MinLength = null;
1290 else
1291 ParameterInfo.MinLength = int.Parse(Value);
1292
1293 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1294 await this.ValidateParameters();
1295 }
1296 catch (Exception)
1297 {
1298 TextBox.Background = Brushes.Salmon;
1299 }
1300 }
1301 catch (Exception ex)
1302 {
1303 Log.Exception(ex);
1304 }
1305 }
1306
1307 private async void Parameter_RegExTextChanged(object sender, RoutedEventArgs e)
1308 {
1309 try
1310 {
1311 if (sender is not TextBox TextBox || TextBox.Tag is not StringParameterInfo ParameterInfo)
1312 return;
1313
1314 try
1315 {
1316 ParameterInfo.RegEx = TextBox.Text;
1317
1318 TextBox.Background = ParameterInfo.Protection.DefaultBrush();
1319 await this.ValidateParameters();
1320 }
1321 catch (Exception)
1322 {
1323 TextBox.Background = Brushes.Salmon;
1324 }
1325 }
1326 catch (Exception ex)
1327 {
1328 Log.Exception(ex);
1329 }
1330 }
1331
1335 public ICommand AddBooleanParameter => this.addBooleanParameter;
1336
1341 {
1342 return this.ExecuteAddBooleanParameter("Boolean", null, defaultParameterDescription);
1343 }
1344
1345 private async Task ExecuteAddBooleanParameter(string Name, bool? Value, params string[] MarkdownDescription)
1346 {
1347 BooleanParameter BP = new()
1348 {
1349 Name = FindNewName(Name, this.AllParameterInfos),
1350 Descriptions = await MarkdownDescription.ToHumanReadableText("en"),
1351 Expression = string.Empty,
1352 Guide = string.Empty,
1353 Value = Value,
1354 Protection = ProtectionLevel.Normal
1355 };
1356
1357 this.AddParameter(this.GetParameterInfo(BP));
1358 }
1359
1360 private ParameterInfo GetParameterInfo(BooleanParameter BP)
1361 {
1362 CheckBox CheckBox = new()
1363 {
1364 VerticalContentAlignment = VerticalAlignment.Center,
1365 HorizontalContentAlignment = HorizontalAlignment.Center
1366 };
1367
1368 CheckBox.SetBinding(CheckBox.IsCheckedProperty, "Value");
1369 CheckBox.Checked += this.Parameter_CheckedChanged;
1370 CheckBox.Unchecked += this.Parameter_CheckedChanged;
1371
1372 ParameterInfo ParameterInfo = new BooleanParameterInfo(this.contract, BP, CheckBox, this, this.parameters);
1373 CheckBox.Tag = ParameterInfo;
1374
1375 return ParameterInfo;
1376 }
1377
1378 private async void Parameter_CheckedChanged(object sender, RoutedEventArgs e)
1379 {
1380 try
1381 {
1382 if (sender is not CheckBox CheckBox || CheckBox.Tag is not ParameterInfo ParameterInfo)
1383 return;
1384
1385 ParameterInfo.Value = CheckBox.IsChecked;
1386
1387 await this.ValidateParameters();
1388 this.RenderHumanReadableMarkdown(this, EventArgs.Empty);
1389 }
1390 catch (Exception ex)
1391 {
1392 Log.Exception(ex);
1393 }
1394 }
1395
1396 private async void Parameter_MinIncludedCheckedChanged(object sender, RoutedEventArgs e)
1397 {
1398 try
1399 {
1400 if (sender is not CheckBox CheckBox || CheckBox.Tag is not RangedParameterInfo ParameterInfo)
1401 return;
1402
1403 ParameterInfo.MinIncluded = CheckBox.IsChecked ?? false;
1404
1405 await this.ValidateParameters();
1406 }
1407 catch (Exception ex)
1408 {
1409 Log.Exception(ex);
1410 }
1411 }
1412
1413 private async void Parameter_MaxIncludedCheckedChanged(object sender, RoutedEventArgs e)
1414 {
1415 try
1416 {
1417 if (sender is not CheckBox CheckBox || CheckBox.Tag is not RangedParameterInfo ParameterInfo)
1418 return;
1419
1420 ParameterInfo.MaxIncluded = CheckBox.IsChecked ?? false;
1421
1422 await this.ValidateParameters();
1423 }
1424 catch (Exception ex)
1425 {
1426 Log.Exception(ex);
1427 }
1428 }
1429
1433 public ICommand AddDateParameter => this.addDateParameter;
1434
1439 {
1440 return this.ExecuteAddDateParameter("Date", null, defaultParameterDescription);
1441 }
1442
1443 private async Task ExecuteAddDateParameter(string Name, DateTime? Value, params string[] MarkdownDescription)
1444 {
1445 DateParameter DP = new()
1446 {
1447 Name = FindNewName(Name, this.AllParameterInfos),
1448 Descriptions = await MarkdownDescription.ToHumanReadableText("en"),
1449 Expression = string.Empty,
1450 Guide = string.Empty,
1451 Max = null,
1452 MaxIncluded = false,
1453 Min = null,
1454 MinIncluded = false,
1455 Value = Value,
1456 Protection = ProtectionLevel.Normal
1457 };
1458
1459 this.AddParameter(this.GetParameterInfo(DP));
1460 }
1461
1462 private ParameterInfo GetParameterInfo(DateParameter DP)
1463 {
1464 TextBox ValueControl = new();
1465 Binding Binding = new("Value")
1466 {
1467 Converter = new DateToXmlString()
1468 };
1469 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1470 ValueControl.TextChanged += this.Parameter_TextChanged;
1471
1472 TextBox MinControl = new();
1473 Binding = new("Min")
1474 {
1475 Converter = new DateToXmlString()
1476 };
1477 MinControl.SetBinding(TextBox.TextProperty, Binding);
1478 MinControl.TextChanged += this.Parameter_MinTextChanged;
1479
1480 TextBox MaxControl = new();
1481 Binding = new Binding("Max")
1482 {
1483 Converter = new DateToXmlString()
1484 };
1485 MaxControl.SetBinding(TextBox.TextProperty, Binding);
1486 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1487
1488 CheckBox MinIncludedControl = new();
1489 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1490 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1491 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1492
1493 CheckBox MaxIncludedControl = new();
1494 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1495 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1496 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1497
1498 ParameterInfo ParameterInfo = new DateParameterInfo(this.contract, DP, ValueControl, MinControl, MinIncludedControl,
1499 MaxControl, MaxIncludedControl, this, this.parameters);
1500 ValueControl.Tag = ParameterInfo;
1501 MinControl.Tag = ParameterInfo;
1502 MaxControl.Tag = ParameterInfo;
1503 MinIncludedControl.Tag = ParameterInfo;
1504 MaxIncludedControl.Tag = ParameterInfo;
1505
1506 return ParameterInfo;
1507 }
1508
1512 public ICommand AddDateTimeParameter => this.addDateTimeParameter;
1513
1518 {
1519 DateTimeParameter DP = new()
1520 {
1521 Name = FindNewName("DateTime", this.AllParameterInfos),
1522 Descriptions = new HumanReadableText[] { await defaultParameterDescription.ToHumanReadableText("en") },
1523 Expression = string.Empty,
1524 Guide = string.Empty,
1525 Max = null,
1526 MaxIncluded = false,
1527 Min = null,
1528 MinIncluded = false,
1529 Value = null,
1530 Protection = ProtectionLevel.Normal
1531 };
1532
1533 this.AddParameter(this.GetParameterInfo(DP));
1534 }
1535
1536 private ParameterInfo GetParameterInfo(DateTimeParameter DP)
1537 {
1538 TextBox ValueControl = new();
1539 Binding Binding = new("Value")
1540 {
1541 Converter = new DateTimeToXmlString()
1542 };
1543 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1544 ValueControl.TextChanged += this.Parameter_TextChanged;
1545
1546 TextBox MinControl = new();
1547 Binding = new Binding("Min")
1548 {
1549 Converter = new DateTimeToXmlString()
1550 };
1551 MinControl.SetBinding(TextBox.TextProperty, Binding);
1552 MinControl.TextChanged += this.Parameter_MinTextChanged;
1553
1554 TextBox MaxControl = new();
1555 Binding = new Binding("Max")
1556 {
1557 Converter = new DateTimeToXmlString()
1558 };
1559 MaxControl.SetBinding(TextBox.TextProperty, Binding);
1560 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1561
1562 CheckBox MinIncludedControl = new();
1563 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1564 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1565 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1566
1567 CheckBox MaxIncludedControl = new();
1568 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1569 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1570 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1571
1572 ParameterInfo ParameterInfo = new DateTimeParameterInfo(this.contract, DP, ValueControl, MinControl, MinIncludedControl,
1573 MaxControl, MaxIncludedControl, this, this.parameters);
1574 ValueControl.Tag = ParameterInfo;
1575 MinControl.Tag = ParameterInfo;
1576 MaxControl.Tag = ParameterInfo;
1577 MinIncludedControl.Tag = ParameterInfo;
1578 MaxIncludedControl.Tag = ParameterInfo;
1579
1580 return ParameterInfo;
1581 }
1582
1586 public ICommand AddTimeParameter => this.addTimeParameter;
1587
1592 {
1593 return this.ExecuteAddTimeParameter("Time", null, defaultParameterDescription);
1594 }
1595
1596 private async Task ExecuteAddTimeParameter(string Name, TimeSpan? Value, params string[] MarkdownDescription)
1597 {
1598 TimeParameter DP = new()
1599 {
1600 Name = FindNewName(Name, this.AllParameterInfos),
1601 Descriptions = await MarkdownDescription.ToHumanReadableText("en"),
1602 Expression = string.Empty,
1603 Guide = string.Empty,
1604 Max = null,
1605 MaxIncluded = false,
1606 Min = null,
1607 MinIncluded = false,
1608 Value = Value,
1609 Protection = ProtectionLevel.Normal
1610 };
1611
1612 this.AddParameter(this.GetParameterInfo(DP));
1613 }
1614
1615 private ParameterInfo GetParameterInfo(TimeParameter DP)
1616 {
1617 TextBox ValueControl = new();
1618 Binding Binding = new("Value")
1619 {
1620 Converter = new TimeToXmlString()
1621 };
1622 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1623 ValueControl.TextChanged += this.Parameter_TextChanged;
1624
1625 TextBox MinControl = new();
1626 Binding = new Binding("Min")
1627 {
1628 Converter = new TimeToXmlString()
1629 };
1630 MinControl.SetBinding(TextBox.TextProperty, Binding);
1631 MinControl.TextChanged += this.Parameter_MinTextChanged;
1632
1633 TextBox MaxControl = new();
1634 Binding = new("Min")
1635 {
1636 Converter = new TimeToXmlString()
1637 };
1638 MaxControl.SetBinding(TextBox.TextProperty, Binding);
1639 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1640
1641 CheckBox MinIncludedControl = new();
1642 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1643 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1644 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1645
1646 CheckBox MaxIncludedControl = new();
1647 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1648 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1649 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1650
1651 ParameterInfo ParameterInfo = new TimeParameterInfo(this.contract, DP, ValueControl, MinControl, MinIncludedControl,
1652 MaxControl, MaxIncludedControl, this, this.parameters);
1653 ValueControl.Tag = ParameterInfo;
1654 MinControl.Tag = ParameterInfo;
1655 MaxControl.Tag = ParameterInfo;
1656 MinIncludedControl.Tag = ParameterInfo;
1657 MaxIncludedControl.Tag = ParameterInfo;
1658
1659 return ParameterInfo;
1660 }
1661
1665 public ICommand AddDurationParameter => this.addDurationParameter;
1666
1671 {
1672 DurationParameter DP = new()
1673 {
1674 Name = FindNewName("Duration", this.AllParameterInfos),
1675 Descriptions = new HumanReadableText[] { await defaultParameterDescription.ToHumanReadableText("en") },
1676 Expression = string.Empty,
1677 Guide = string.Empty,
1678 Max = null,
1679 MaxIncluded = false,
1680 Min = null,
1681 MinIncluded = false,
1682 Value = null,
1683 Protection = ProtectionLevel.Normal
1684 };
1685
1686 this.AddParameter(this.GetParameterInfo(DP));
1687 }
1688
1689 private ParameterInfo GetParameterInfo(DurationParameter DP)
1690 {
1691 TextBox ValueControl = new();
1692 Binding Binding = new("Value")
1693 {
1694 Converter = new DurationToXmlString()
1695 };
1696 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1697 ValueControl.TextChanged += this.Parameter_TextChanged;
1698
1699 TextBox MinControl = new();
1700 Binding = new Binding("Min")
1701 {
1702 Converter = new DurationToXmlString()
1703 };
1704 MinControl.SetBinding(TextBox.TextProperty, Binding);
1705 MinControl.TextChanged += this.Parameter_MinTextChanged;
1706
1707 TextBox MaxControl = new();
1708 Binding = new Binding("Max")
1709 {
1710 Converter = new DurationToXmlString()
1711 };
1712 MaxControl.SetBinding(TextBox.TextProperty, Binding);
1713 MaxControl.TextChanged += this.Parameter_MaxTextChanged;
1714
1715 CheckBox MinIncludedControl = new();
1716 MinIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MinIncluded");
1717 MinIncludedControl.Checked += this.Parameter_MinIncludedCheckedChanged;
1718 MinIncludedControl.Unchecked += this.Parameter_MinIncludedCheckedChanged;
1719
1720 CheckBox MaxIncludedControl = new();
1721 MaxIncludedControl.SetBinding(CheckBox.IsCheckedProperty, "MaxIncluded");
1722 MaxIncludedControl.Checked += this.Parameter_MaxIncludedCheckedChanged;
1723 MaxIncludedControl.Unchecked += this.Parameter_MaxIncludedCheckedChanged;
1724
1725 ParameterInfo ParameterInfo = new DurationParameterInfo(this.contract, DP, ValueControl, MinControl, MinIncludedControl,
1726 MaxControl, MaxIncludedControl, this, this.parameters);
1727 ValueControl.Tag = ParameterInfo;
1728 MinControl.Tag = ParameterInfo;
1729 MaxControl.Tag = ParameterInfo;
1730 MinIncludedControl.Tag = ParameterInfo;
1731 MaxIncludedControl.Tag = ParameterInfo;
1732
1733 return ParameterInfo;
1734 }
1735
1739 public ICommand AddCalcParameter => this.addCalcParameter;
1740
1744 public async Task ExecuteAddCalcParameter()
1745 {
1746 CalcParameter CP = new()
1747 {
1748 Name = FindNewName("Calc", this.AllParameterInfos),
1749 Descriptions = new HumanReadableText[] { await defaultParameterDescription.ToHumanReadableText("en") },
1750 Expression = string.Empty,
1751 Guide = string.Empty,
1752 Protection = ProtectionLevel.Normal
1753 };
1754
1755 this.AddParameter(this.GetParameterInfo(CP));
1756 }
1757
1761 public ICommand AddRoleReference => this.addRoleReference;
1762
1766 public async Task ExecuteAddRoleReference()
1767 {
1768 RoleParameter RP = new()
1769 {
1770 Name = FindNewName("RoleRef", this.AllParameterInfos),
1771 Descriptions = new HumanReadableText[] { await defaultParameterDescription.ToHumanReadableText("en") },
1772 Expression = string.Empty,
1773 Guide = string.Empty,
1774 Index = 1,
1775 Property = string.Empty,
1776 Role = string.Empty,
1777 Required = false,
1778 Protection = ProtectionLevel.Normal
1779 };
1780
1781 this.AddRoleReferenceParameter(this.GetParameterInfo(RP));
1782 }
1783
1784 private RoleReferenceParameterInfo GetParameterInfo(RoleParameter RP)
1785 {
1786 TextBox ValueControl = new()
1787 {
1788 IsReadOnly = true
1789 };
1790
1791 RoleReferenceParameterInfo ParameterInfo = new(this.contract, RP, ValueControl, this, this.roleReferenceParameters);
1792 ValueControl.Tag = ParameterInfo;
1793
1794 return ParameterInfo;
1795 }
1796
1800 public ICommand AddContractReference => this.addContractReference;
1801
1806 {
1807 ContractReferenceParameter CRP = new()
1808 {
1809 Name = FindNewName("ContractRef", this.AllParameterInfos),
1810 Descriptions = new HumanReadableText[] { await defaultParameterDescription.ToHumanReadableText("en") },
1811 Labels = new Waher.Networking.XMPP.Contracts.HumanReadable.Label[] { await defaultParameterLabel.ToHumanReadableLabel("en") },
1812 Expression = string.Empty,
1813 Guide = string.Empty,
1814 CreatorRole = string.Empty,
1815 LocalName = string.Empty,
1816 Namespace = string.Empty,
1817 Provider = string.Empty,
1818 Required = false,
1819 TemplateId = string.Empty,
1820 Protection = ProtectionLevel.Normal,
1821 Value = string.Empty
1822 };
1823
1824 this.AddContractReferenceParameter(this.GetParameterInfo(CRP));
1825 }
1826
1828 {
1829 TextBox ValueControl = new();
1830 ValueControl.SetBinding(TextBox.TextProperty, "ContractId");
1831 ValueControl.TextChanged += this.Parameter_TextChanged;
1832
1833 ContractReferenceParameterInfo ParameterInfo = new(this.contract, CRP, ValueControl, this, this.contractReferenceParameters);
1834 ValueControl.Tag = ParameterInfo;
1835
1836 return ParameterInfo;
1837 }
1838
1839 private ParameterInfo GetParameterInfo(CalcParameter CP)
1840 {
1841 TextBox ValueControl = new()
1842 {
1843 IsReadOnly = true
1844 };
1845 Binding Binding = new("Value")
1846 {
1847 Converter = new MoneyToString()
1848 };
1849 ValueControl.SetBinding(TextBox.TextProperty, Binding);
1850
1851 ParameterInfo ParameterInfo = new CalcParameterInfo(this.contract, CP, ValueControl, this, this.parameters);
1852 ValueControl.Tag = ParameterInfo;
1853
1854 return ParameterInfo;
1855 }
1856
1857 private void AddParameter(ParameterInfo Parameter)
1858 {
1860 int c = Parameters.Length;
1861
1862 Array.Resize(ref Parameters, c + 1);
1863 Parameters[c] = Parameter;
1864
1865 this.Parameters = Parameters;
1866 }
1867
1873 {
1875 int i = Array.IndexOf(Parameters, Parameter);
1876 if (i < 0)
1877 return;
1878
1879 int c = Parameters.Length;
1880
1881 if (i < c - 1)
1882 Array.Copy(Parameters, i + 1, Parameters, i, c - i - 1);
1883
1884 Array.Resize(ref Parameters, c - 1);
1885
1886 this.Parameters = Parameters;
1887 }
1888
1889 private void AddRoleReferenceParameter(RoleReferenceParameterInfo Parameter)
1890 {
1892 int c = Parameters.Length;
1893
1894 Array.Resize(ref Parameters, c + 1);
1895 Parameters[c] = Parameter;
1896
1897 this.RoleReferenceParameters = Parameters;
1898 }
1899
1905 {
1907 int i = Array.IndexOf(Parameters, Parameter);
1908 if (i < 0)
1909 return;
1910
1911 int c = Parameters.Length;
1912
1913 if (i < c - 1)
1914 Array.Copy(Parameters, i + 1, Parameters, i, c - i - 1);
1915
1916 Array.Resize(ref Parameters, c - 1);
1917
1918 this.RoleReferenceParameters = Parameters;
1919 }
1920
1921 private void AddContractReferenceParameter(ContractReferenceParameterInfo Parameter)
1922 {
1924 int c = Parameters.Length;
1925
1926 Array.Resize(ref Parameters, c + 1);
1927 Parameters[c] = Parameter;
1928
1929 this.ContractReferenceParameters = Parameters;
1930 }
1931
1937 {
1939 int i = Array.IndexOf(Parameters, Parameter);
1940 if (i < 0)
1941 return;
1942
1943 int c = Parameters.Length;
1944
1945 if (i < c - 1)
1946 Array.Copy(Parameters, i + 1, Parameters, i, c - i - 1);
1947
1948 Array.Resize(ref Parameters, c - 1);
1949
1950 this.ContractReferenceParameters = Parameters;
1951 }
1952
1956 public ICommand New => this.@new;
1957
1958 private Task ExecuteNewContract()
1959 {
1960 return this.ExecuteNewContract(true);
1961 }
1962
1963 private async Task ExecuteNewContract(bool QueryUser)
1964 {
1965 try
1966 {
1967 if (QueryUser &&
1968 MessageBox.Show("Are you sure you want clear the form and lose all data that has not been saved?", "Confirm",
1969 MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.No) != MessageBoxResult.Yes)
1970 {
1971 return;
1972 }
1973
1974 this.Visibility = ContractVisibility.Public;
1975 this.PartsMode = ContractParts.TemplateOnly;
1976 this.ArchiveOptional = Waher.Content.Duration.Zero;
1977 this.ArchiveRequired = Waher.Content.Duration.Zero;
1978 this.Duration = Waher.Content.Duration.Zero;
1979 this.Language = "en";
1980 this.Languages = Array.Empty<Iso__639_1.Record>();
1981 this.SignBefore = null;
1982 this.SignAfter = null;
1983 this.Roles = Array.Empty<RoleInfo>();
1984 this.Parts = Array.Empty<PartInfo>();
1985 this.Parameters = Array.Empty<ParameterInfo>();
1986 this.RoleReferenceParameters = Array.Empty<RoleReferenceParameterInfo>();
1987 this.MachineReadable = string.Empty;
1988 this.ForMachines = null;
1989 this.ContractId = string.Empty;
1990 this.HumanReadableMarkdown = string.Empty;
1991 this.HumanReadable = null;
1992
1993 await this.GenerateContract();
1994 }
1995 catch (Exception ex)
1996 {
1997 Log.Exception(ex);
1998 }
1999 }
2000
2004 public ICommand LoadCommand => this.load;
2005
2006 private async Task ExecuteLoadContract()
2007 {
2008 try
2009 {
2010 OpenFileDialog Dialog = new()
2011 {
2012 CheckFileExists = true,
2013 CheckPathExists = true,
2014 DefaultExt = "xml",
2015 Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
2016 Multiselect = false,
2017 ShowReadOnly = true,
2018 Title = "Load Smart Contract"
2019 };
2020
2021 bool? Result = Dialog.ShowDialog(MainWindow.currentInstance);
2022 if (!Result.HasValue || !Result.Value)
2023 return;
2024
2025 XmlDocument Doc = new()
2026 {
2027 PreserveWhitespace = true
2028 };
2029
2030 Doc.Load(Dialog.FileName);
2031
2033 Contract Contract = Parsed.Contract
2034 ?? throw new InvalidOperationException("Not a valid Smart Contract file.");
2035
2037 throw new InvalidOperationException("Contract is not a template.");
2038
2039 await this.SetContract(Contract);
2040 }
2041 catch (Exception ex)
2042 {
2043 MainWindow.ErrorBox(ex.Message);
2044 }
2045 }
2046
2050 public ICommand SaveCommand => this.save;
2051
2052 private Task ExecuteSaveContract()
2053 {
2054 try
2055 {
2056 SaveFileDialog Dialog = new()
2057 {
2058 AddExtension = true,
2059 CheckFileExists = false,
2060 CheckPathExists = true,
2061 CreatePrompt = false,
2062 DefaultExt = "xml",
2063 Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
2064 OverwritePrompt = true,
2065 Title = "Save Smart Contract"
2066 };
2067
2068 bool? Result = Dialog.ShowDialog(MainWindow.currentInstance);
2069 if (!Result.HasValue || !Result.Value)
2070 return Task.CompletedTask;
2071
2072 string Xml = this.contract.ToXml();
2073 (string Pretty, XmlElement Parsed) = Xml.ToPrettyXml();
2074
2075 File.WriteAllText(Dialog.FileName, Pretty);
2076 }
2077 catch (Exception ex)
2078 {
2079 MainWindow.ErrorBox(ex.Message);
2080 }
2081
2082 return Task.CompletedTask;
2083 }
2084
2088 public ICommand ImportCommand => this.import;
2089
2090 private async Task ExecuteImportContract()
2091 {
2092 try
2093 {
2094 OpenFileDialog Dialog = new()
2095 {
2096 CheckFileExists = true,
2097 CheckPathExists = true,
2098 DefaultExt = "docx",
2099 Filter = "Microsoft Word Files (*.docx)|*.docx",
2100 Multiselect = false,
2101 ShowReadOnly = true,
2102 Title = "Import from Microsoft Word"
2103 };
2104
2105 bool? Result = Dialog.ShowDialog(MainWindow.currentInstance);
2106 if (!Result.HasValue || !Result.Value)
2107 return;
2108
2109 string Markdown;
2110 string TempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString().Replace("-", string.Empty)) + ".docx";
2111 string Language;
2112
2113 try
2114 {
2115 File.Copy(Dialog.FileName, TempFileName, true);
2116 Markdown = WordUtilities.ExtractAsMarkdown(TempFileName, out Language);
2117 }
2118 finally
2119 {
2120 File.Delete(TempFileName);
2121 }
2122
2123 await this.ExecuteNewContract(false);
2124
2125 if (ContractUtilities.ExtractParameters(ref Markdown, out Dictionary<string, ParameterInformation> HeaderInfo))
2126 {
2127 foreach (KeyValuePair<string, ParameterInformation> P in HeaderInfo)
2128 {
2129 switch (P.Value.Type)
2130 {
2131 case ParameterType.String:
2132 default:
2133 await this.ExecuteAddStringParameter(P.Value.Name, null, P.Value.MaxLength,
2134 GetDescriptions(P.Value.Values));
2135 break;
2136
2137 case ParameterType.Boolean:
2138 if ((P.Value.Values?.Count ?? 0) > 0 && CommonTypes.TryParse(P.Value.Values[0], out bool b))
2139 await this.ExecuteAddBooleanParameter(P.Value.Name, b, defaultParameterDescription);
2140 else
2141 await this.ExecuteAddBooleanParameter(P.Value.Name, null, defaultParameterDescription);
2142 break;
2143
2144 case ParameterType.StringWithOptions:
2145 StringBuilder RegEx = new();
2146 bool First = true;
2147
2148 foreach (OptionInformation Option in P.Value.Options)
2149 {
2150 if (First)
2151 First = false;
2152 else
2153 RegEx.Append('|');
2154
2155 RegEx.Append(CommonTypes.RegexStringEncode(Option.Value));
2156 RegEx.Append(".*");
2157 }
2158
2159 RegEx.Append("|.*");
2160
2161 await this.ExecuteAddStringParameter(P.Value.Name, RegEx.ToString(), P.Value.MaxLength,
2162 GetDescriptions(P.Value.Values));
2163 break;
2164
2165 case ParameterType.ListOfOptions:
2166 RegEx = new();
2167 First = true;
2168
2169 RegEx.Append("^(");
2170
2171 foreach (OptionInformation Option in P.Value.Options)
2172 {
2173 if (First)
2174 First = false;
2175 else
2176 RegEx.Append('|');
2177
2178 RegEx.Append(CommonTypes.RegexStringEncode(Option.Value));
2179 }
2180
2181 RegEx.Append(")$");
2182
2183 await this.ExecuteAddStringParameter(P.Value.Name, RegEx.ToString(), P.Value.MaxLength,
2184 GetDescriptions(P.Value.Values));
2185 break;
2186
2187 case ParameterType.Date:
2188 if ((P.Value.Values?.Count ?? 0) > 0 && DateTime.TryParse(P.Value.Values[0], out DateTime TP))
2189 await this.ExecuteAddDateParameter(P.Value.Name, TP, defaultParameterDescription);
2190 else
2191 await this.ExecuteAddDateParameter(P.Value.Name, null, defaultParameterDescription);
2192 break;
2193
2194 case ParameterType.Time:
2195 if ((P.Value.Values?.Count ?? 0) > 0 && TimeSpan.TryParse(P.Value.Values[0], out TimeSpan TS))
2196 await this.ExecuteAddTimeParameter(P.Value.Name, TS, defaultParameterDescription);
2197 else
2198 await this.ExecuteAddTimeParameter(P.Value.Name, null, defaultParameterDescription);
2199 break;
2200
2201 case ParameterType.Number:
2202 if ((P.Value.Values?.Count ?? 0) > 0 && CommonTypes.TryParse(P.Value.Values[0], out decimal d))
2203 await this.ExecuteAddNumericParameter(P.Value.Name, d, defaultParameterDescription);
2204 else
2205 await this.ExecuteAddNumericParameter(P.Value.Name, null, defaultParameterDescription);
2206 break;
2207 }
2208 }
2209 }
2210
2211 if (string.IsNullOrEmpty(Language))
2212 Language = this.Language;
2213 else
2214 {
2215 this.Languages = new string[] { Language }.ToIso639_1();
2216 this.Language = Language;
2217 }
2218
2219 HumanReadableText Text = await Markdown.ToHumanReadableText(Language);
2220 Markdown = await Text.GenerateMarkdown(this.Contract);
2221
2222 StringBuilder sb = new();
2223 Text.Serialize(sb);
2224
2225 XmlDocument Doc = new();
2226 Doc.LoadXml(sb.ToString());
2227
2228 LinkedList<XmlElement> Elements = new();
2229 Elements.AddLast(Doc.DocumentElement);
2230
2231 while (Elements.First is not null)
2232 {
2233 XmlElement E = Elements.First.Value;
2234 Elements.RemoveFirst();
2235
2236 if (E.LocalName == "parameter")
2237 {
2238 string ParameterName = XML.Attribute(E, "name");
2239 if (!string.IsNullOrEmpty(ParameterName))
2240 Markdown = Markdown.Replace("`" + ParameterName + "`", "[%" + ParameterName + "]");
2241 }
2242
2243 foreach (XmlNode N in E.ChildNodes)
2244 {
2245 if (N is XmlElement E2)
2246 Elements.AddLast(E2);
2247 }
2248 }
2249
2250 this.HumanReadableMarkdown = Markdown;
2251 this.MachineReadable = "<Nop xmlns=\"https://paiwise.tagroot.io/Schema/PaymentInstructions.xsd\" />";
2252 this.ContractId = Path.GetFileName(Path.ChangeExtension(Dialog.FileName, string.Empty));
2253
2254 await this.ValidateParameters();
2255 }
2256 catch (Exception ex)
2257 {
2258 MainWindow.ErrorBox(ex.Message);
2259 }
2260 }
2261
2262 private static string[] GetDescriptions(List<string> Descriptions)
2263 {
2264 if (Descriptions is null || Descriptions.Count == 0 ||
2265 (Descriptions.Count == 1 && string.IsNullOrEmpty(Descriptions[0])))
2266 {
2267 return new string[] { defaultParameterDescription };
2268 }
2269 else
2270 return Descriptions.ToArray();
2271 }
2272
2276 public ICommand AddLanguage => this.addLanguage;
2277
2278 private Task ExecuteAddLanguage()
2279 {
2280 AddLanguageDialog Dialog = new();
2281 AddLanguageModel Model = new(Dialog);
2282
2283 bool? Result = Dialog.ShowDialog();
2284 if (!Result.HasValue || !Result.Value)
2285 return Task.CompletedTask;
2286
2287 string Language = Model.SelectedLanguage;
2288 if (string.IsNullOrEmpty(Language))
2289 return Task.CompletedTask;
2290
2291 this.Languages = this.Languages.ToCodes().Append(Language).ToIso639_1();
2292 this.Language = Language.ToLower();
2293
2294 return Task.CompletedTask;
2295 }
2296
2300 public ICommand RemoveLanguage => this.removeLanguage;
2301
2302 private bool CanExecuteRemoveLanguage()
2303 {
2304 return !string.IsNullOrEmpty(this.Language) && this.Languages.Length >= 2;
2305 }
2306
2307 private Task ExecuteRemoveLanguage()
2308 {
2309 string Language = this.Language;
2310
2311 if (MessageBox.Show("Are you sure you want to remove language " + Language + " from the contract?", "Confirm",
2312 MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.No) != MessageBoxResult.Yes)
2313 {
2314 return Task.CompletedTask;
2315 }
2316
2317 foreach (ParameterInfo PI in this.AllParameterInfos)
2318 PI.Parameter.Descriptions = PI.Parameter.Descriptions.Remove(Language);
2319
2320 foreach (RoleInfo RI in this.Roles)
2321 RI.Role.Descriptions = RI.Role.Descriptions.Remove(Language);
2322
2323 this.contract.ForHumans = this.contract.ForHumans.Remove(Language);
2324
2325 this.Languages = this.Languages.ToCodes().Remove(Language).ToIso639_1();
2326 this.Language = this.contract.DefaultLanguage;
2327
2328 return Task.CompletedTask;
2329 }
2330
2334 public string OpenAiKey
2335 {
2336 get => this.openAiKey.Value;
2337 set => this.openAiKey.Value = value;
2338 }
2339
2343 public ICommand Propose => this.propose;
2344
2345 private bool CanExecuteProposeContract()
2346 {
2347 return this.Connected &&
2348 (this.ParametersOk || this.PartsMode == ContractParts.TemplateOnly) &&
2349 !string.IsNullOrEmpty(this.ContractId) &&
2350 this.contract.ForMachines is not null;
2351 }
2352
2354 protected override Task StateChanged(XmppState NewState)
2355 {
2356 this.propose.RaiseCanExecuteChanged();
2357 return base.StateChanged(NewState);
2358 }
2359
2360 private async Task ExecuteProposeContract()
2361 {
2362 try
2363 {
2365
2366 if (MessageBox.Show("Are you sure you want to propose the designed template to " + LegalModel.Contracts.ComponentAddress + "?", "Confirm",
2367 MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.No) != MessageBoxResult.Yes)
2368 {
2369 return;
2370 }
2371
2373
2374 Contract Contract = await LegalModel.Contracts.CreateContractAsync(this.contract.ForMachines, this.contract.ForHumans, this.contract.Roles,
2375 this.contract.Parts, this.contract.Parameters, this.contract.Visibility, this.contract.PartsMode, this.contract.Duration,
2376 this.contract.ArchiveRequired, this.contract.ArchiveOptional, this.contract.SignAfter, this.contract.SignBefore,
2377 this.contract.CanActAsTemplate);
2378
2379 await RuntimeSettings.SetAsync("Contract.Template." + this.ContractId, Contract.ContractId);
2381
2382 MainWindow.SuccessBox("Template successfully proposed. The template ID, which has been copied to the clipboard, is: " + Contract.ContractId);
2383 Clipboard.SetText(Contract.ContractId);
2384 }
2385 catch (Exception ex)
2386 {
2387 MainWindow.ErrorBox(ex.Message);
2388 }
2389 }
2390 }
2391}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static string RegexStringEncode(string s)
Encodes a string for inclusion in a regular expression.
Definition: CommonTypes.cs:813
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Definition: CommonTypes.cs:46
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Definition: XML.cs:914
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
Contains a reference to an attachment assigned to a legal object.
Definition: Attachment.cs:9
Calculation contractual parameter
Represents a digital signature on a contract.
Contains the definition of a contract
Definition: Contract.cs:22
static Task< ParsedContract > Parse(XmlDocument Xml)
Validates a contract XML Document, and returns the contract definition in it.
Definition: Contract.cs:397
string[] GetLanguages()
Gets available languages encoded in contract.
Definition: Contract.cs:1901
Parameter[] Parameters
Defined parameters for the smart contract.
Definition: Contract.cs:267
Duration? ArchiveRequired
Requied time to archive a signed smart contract, after it becomes obsolete.
Definition: Contract.cs:202
HumanReadableText[] ForHumans
Human-readable contents of the contract.
Definition: Contract.cs:300
Duration? ArchiveOptional
Optional time to archive a signed smart contract, after it becomes obsolete, and after its required a...
Definition: Contract.cs:211
bool CanActAsTemplate
If the contract can act as a template for other contracts.
Definition: Contract.cs:336
XmlElement ForMachines
Machine-readable contents of the contract.
Definition: Contract.cs:276
Role[] Roles
Roles defined in the smart contract.
Definition: Contract.cs:240
DateTime? SignAfter
Signatures will only be accepted after this point in time.
Definition: Contract.cs:166
string DefaultLanguage
Default language for contract.
Definition: Contract.cs:1884
ContractParts PartsMode
How parts are defined in the smart contract.
Definition: Contract.cs:249
Task< string > ToMarkdown(string Language)
Creates a human-readable Markdown document for the contract.
Definition: Contract.cs:1942
string ContractId
Contract identity
Definition: Contract.cs:65
Part[] Parts
Defined parts for the smart contract.
Definition: Contract.cs:258
Duration? Duration
Duration of the contract. Is counted from the time it is signed by the required parties.
Definition: Contract.cs:193
DateTime? SignBefore
Signatures will only be accepted until this point in time.
Definition: Contract.cs:175
ContractVisibility Visibility
Contrat Visibility
Definition: Contract.cs:184
Task< Contract > CreateContractAsync(XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract.
object Value
Value of parameter. Can be set by event handler, to format the value before it is being displayed.
Task< string > GenerateMarkdown(Contract Contract)
Generates markdown for the human-readable text.
static HumanReadableText Parse(XmlElement Xml)
Class representing human-readable text.
override void Serialize(StringBuilder Xml)
Serializes the element in normalized form.
HumanReadableText[] Descriptions
Discriptions of the object, in different languages.
Abstract base class for contractual parameters
Definition: Parameter.cs:17
abstract void Populate(Variables Variables)
Populates a variable collection with the value of the parameter.
Contains information about a parsed contract.
Class defining a part in a contract
Definition: Part.cs:30
Class defining a role
Definition: Role.cs:7
Role-reference contractual parameter
Represents a server signature on a contract.
String-valued contractual parameter
Static class managing persistent settings.
static async Task< bool > SetAsync(string Key, string Value)
Sets a string-valued setting.
Class managing a script expression.
Definition: Expression.cs:39
Collection of variables.
Definition: Variables.cs:25
ContractParts
How the parts of the contract are defined.
Definition: Part.cs:9
ProtectionLevel
Parameter protection levels
ContractVisibility
Visibility types for contracts.
Definition: Enumerations.cs:58
XmppState
State of XMPP connection.
Definition: XmppState.cs:7
Definition: App.xaml.cs:4
Represents a duration value, as defined by the xsd:duration data type: http://www....
Definition: Duration.cs:13
static readonly Duration Zero
Zero value
Definition: Duration.cs:532