Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
TreeNode.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
4using System.Xml;
5using System.Windows;
6using System.Windows.Controls;
7using System.Windows.Input;
8using System.Windows.Media;
9using System.Windows.Media.Imaging;
11using Waher.Events;
17
19{
23 public abstract class TreeNode : SelectableItem, IDisposable
24 {
25 private readonly TreeNode parent;
26 protected DisplayableParameters parameters = null;
27 protected SortedDictionary<string, TreeNode> children = null;
28 private object tag = null;
29 private bool expanded = false;
30
36 {
37 this.parent = Parent;
38 }
39
43 public abstract string Key
44 {
45 get;
46 }
47
52 public bool? HasChildren
53 {
54 get
55 {
56 if (this.children is null)
57 return null;
58 else
59 {
60 lock (this.children)
61 {
62 return this.children.Count > 0;
63 }
64 }
65 }
66 }
67
72 {
73 get
74 {
75 if (this.children is null)
76 return null;
77
79
80 lock (this.children)
81 {
82 Children = new TreeNode[this.children.Count];
83 this.children.Values.CopyTo(Children, 0);
84 }
85
86 return Children;
87 }
88 }
89
96 public bool TryGetChild(string ChildKey, out TreeNode Child)
97 {
98 lock (this.children)
99 {
100 return this.children.TryGetValue(ChildKey, out Child);
101 }
102 }
103
107 public TreeNode Parent => this.parent;
108
112 public object Tag
113 {
114 get => this.tag;
115 set => this.tag = value;
116 }
117
121 public abstract string Header
122 {
123 get;
124 }
125
129 public virtual void Dispose()
130 {
131 }
132
137 public abstract void Write(XmlWriter Output);
138
142 public abstract ImageSource ImageResource
143 {
144 get;
145 }
146
150 public virtual Visibility ImageResourceVisibility
151 {
152 get { return Visibility.Visible; }
153 }
154
158 public virtual ImageSource ImageResource2
159 {
160 get { return null; }
161 }
162
166 public virtual Visibility ImageResource2Visibility
167 {
168 get { return Visibility.Hidden; }
169 }
170
174 public abstract string ToolTip
175 {
176 get;
177 }
178
182 public abstract string TypeName
183 {
184 get;
185 }
186
192 public virtual string this[string DisplayableParameter]
193 {
194 get
195 {
196 if (!(this.parameters is null))
197 return this.parameters[DisplayableParameter];
198 else
199 return string.Empty;
200 }
201 }
202
203 public virtual void Add(params Parameter[] Parameters)
204 {
205 if (this.parameters is null)
206 this.parameters = new DisplayableParameters(Parameters);
207 else
208 this.parameters.AddRange(Parameters);
209 }
210
214 public virtual DisplayableParameters DisplayableParameters => this.parameters;
215
219 public event EventHandler Updated = null;
220
224 public virtual void OnUpdated()
225 {
226 this.Raise(this.Updated);
227 }
228
232 public bool IsExpanded
233 {
234 get => this.expanded;
235 set
236 {
237 if (this.expanded != value)
238 {
239 this.expanded = value;
240
241 if (this.expanded)
242 this.OnExpanded();
243 else
244 this.OnCollapsed();
245 }
246 }
247 }
248
252 public event EventHandler Expanded = null;
253
257 public event EventHandler Collapsed = null;
258
262 protected virtual void OnExpanded()
263 {
264 this.LoadChildren();
265 this.Raise(this.Expanded);
266 }
267
271 protected override void OnSelected()
272 {
273 this.LoadChildren();
274 base.OnSelected();
275 }
276
277 protected virtual bool IsLoaded
278 {
279 get
280 {
281 if (this.children is null)
282 return true;
283
284 lock (this.children)
285 {
286 return this.children.Count != 1 || !this.children.ContainsKey(string.Empty);
287 }
288 }
289 }
290
294 protected virtual void LoadChildren()
295 {
296 // Do nothing by default.
297 }
298
302 protected virtual void UnloadChildren()
303 {
304 // Do nothing by default.
305 }
306
310 protected virtual void UnloadGrandchildren()
311 {
312 if (!(this.children is null))
313 {
314 foreach (TreeNode Node in this.children.Values)
315 Node.UnloadChildren();
316 }
317 }
318
322 protected virtual void LoadSiblings()
323 {
324 this.parent?.LoadChildren();
325 }
326
330 protected virtual void OnCollapsed()
331 {
332 this.UnloadGrandchildren();
333 this.Raise(this.Collapsed);
334 }
335
339 public abstract bool CanAddChildren
340 {
341 get;
342 }
343
348 public virtual void Add()
349 {
350 throw new NotSupportedException();
351 }
352
356 public abstract bool CanDelete
357 {
358 get;
359 }
360
364 public virtual bool CustomDeleteQuestion => false;
365
371 public virtual Task Delete(TreeNode Parent, EventHandler OnDeleted)
372 {
373 Parent?.RemoveChild(this);
374 OnDeleted.Raise(this, EventArgs.Empty);
375 return Task.CompletedTask;
376 }
377
381 public abstract bool CanEdit
382 {
383 get;
384 }
385
390 public virtual void Edit()
391 {
392 throw new NotSupportedException();
393 }
394
398 public virtual bool CanCopy
399 {
400 get => false;
401 }
402
407 public virtual void Copy()
408 {
409 throw new NotSupportedException();
410 }
411
415 public virtual bool CanPaste
416 {
417 get => false;
418 }
419
424 public virtual void Paste()
425 {
426 throw new NotSupportedException();
427 }
428
432 public abstract bool CanRecycle
433 {
434 get;
435 }
436
442 public virtual Task Recycle(MainWindow Window)
443 {
444 throw new NotSupportedException();
445 }
446
452 public virtual bool RemoveChild(TreeNode Node)
453 {
454 if (!(this.children is null))
455 {
456 lock (this.children)
457 {
458 return this.children.Remove(Node.Key);
459 }
460 }
461 else
462 return false;
463 }
464
465 internal void RenameChild(string OldKey, string NewKey, TreeNode Node)
466 {
467 if (!(this.children is null))
468 {
469 lock (this.children)
470 {
471 this.children.Remove(OldKey);
472 this.children[NewKey] = Node;
473 }
474 }
475 }
476
480 public virtual bool IsSniffable
481 {
482 get { return false; }
483 }
484
490 public virtual void AddSniffer(ISniffer Sniffer)
491 {
492 throw new NotSupportedException();
493 }
494
501 public virtual Task<bool> RemoveSniffer(ISniffer Sniffer)
502 {
503 throw new NotSupportedException();
504 }
505
509 public virtual bool CanChat => false;
510
518 public virtual Task SendChatMessage(string Message, string ThreadId, MarkdownDocument Markdown)
519 {
520 MainWindow.ErrorBox("You are not allowed to chat with this entity.");
521 return Task.CompletedTask;
522 }
523
528 public virtual void Added(MainWindow Window)
529 {
530 }
531
536 public virtual void Removed(MainWindow Window)
537 {
538 }
539
543 public virtual bool CanReadSensorData => false;
544
548 public virtual bool CanSubscribeToSensorData => false;
549
554 public virtual Task<SensorDataClientRequest> StartSensorDataMomentaryReadout()
555 {
556 throw new NotSupportedException();
557 }
558
563 public virtual Task<SensorDataClientRequest> StartSensorDataFullReadout()
564 {
565 throw new NotSupportedException();
566 }
567
573 public virtual Task<SensorDataSubscriptionRequest> SubscribeSensorDataMomentaryReadout(FieldSubscriptionRule[] Rules)
574 {
575 throw new NotSupportedException();
576 }
577
581 public virtual bool CanConfigure => false;
582
586 public virtual void Configure()
587 {
588 Mouse.OverrideCursor = Cursors.Wait;
589 this.GetConfigurationForm((Sender, e2) =>
590 {
591 if (e2.Ok && !(e2.Form is null))
592 MainWindow.UpdateGui(MainWindow.currentInstance.ShowForm, e2.Form);
593 else
594 MainWindow.UpdateGui(MainWindow.currentInstance.ShowError, e2);
595
596 return Task.CompletedTask;
597 }, null);
598 }
599
606 public virtual Task GetConfigurationForm(EventHandlerAsync<DataFormEventArgs> Callback, object State)
607 {
608 throw new NotSupportedException();
609 }
610
614 public virtual bool CanSearch
615 {
616 get { return false; }
617 }
618
622 public virtual void Search()
623 {
624 throw new NotSupportedException();
625 }
626
632 public virtual void AddContexMenuItems(ref string CurrentGroup, ContextMenu Menu)
633 {
634 if (this.CanAddChildren)
635 {
636 CurrentGroup = "Edit";
637 Menu.Items.Add(new MenuItem()
638 {
639 Header = "_Add...",
640 IsEnabled = true,
641 Command = MainWindow.Add,
642 Icon = new Image()
643 {
644 Source = new BitmapImage(new Uri("../Graphics/Add.png", UriKind.Relative)),
645 Width = 16,
646 Height = 16
647 }
648 });
649 }
650
651 if (!(this.Parent is null) && this.Parent.CanDelete)
652 {
653 CurrentGroup = "Edit";
654 Menu.Items.Add(new MenuItem()
655 {
656 Header = "_Delete...",
657 IsEnabled = true,
658 Command = MainWindow.Delete,
659 Icon = new Image()
660 {
661 Source = new BitmapImage(new Uri("../Graphics/delete_32_h.png", UriKind.Relative)),
662 Width = 16,
663 Height = 16
664 }
665 });
666 }
667
668 if (this.CanCopy)
669 {
670 CurrentGroup = "Edit";
671 Menu.Items.Add(new MenuItem()
672 {
673 Header = "_Copy",
674 IsEnabled = true,
675 Command = MainWindow.Copy,
676 Icon = new Image()
677 {
678 Source = new BitmapImage(new Uri("../Graphics/Amitjakhu-Drip-Copy.16.png", UriKind.Relative)),
679 Width = 16,
680 Height = 16
681 }
682 });
683 }
684 if (this.CanPaste)
685 {
686 CurrentGroup = "Edit";
687 Menu.Items.Add(new MenuItem()
688 {
689 Header = "_Paste",
690 IsEnabled = true,
691 Command = MainWindow.Paste,
692 Icon = new Image()
693 {
694 Source = new BitmapImage(new Uri("../Graphics/Amitjakhu-Drip-Clipboard.16.png", UriKind.Relative)),
695 Width = 16,
696 Height = 16
697 }
698 });
699 }
700
701 if (this.CanRecycle)
702 {
703 this.GroupSeparator(ref CurrentGroup, "Connection", Menu);
704 Menu.Items.Add(new MenuItem()
705 {
706 Header = "_Refresh",
707 IsEnabled = true,
708 Command = MainWindow.Refresh,
709 Icon = new Image()
710 {
711 Source = new BitmapImage(new Uri("../Graphics/refresh_document_16_h.png", UriKind.Relative)),
712 Width = 16,
713 Height = 16
714 }
715 });
716 }
717
718 if (this.IsSniffable)
719 {
720 this.GroupSeparator(ref CurrentGroup, "Connection", Menu);
721 Menu.Items.Add(new MenuItem()
722 {
723 Header = "_Sniff...",
724 IsEnabled = true,
725 Command = MainWindow.Sniff,
726 Icon = new Image()
727 {
728 Source = new BitmapImage(new Uri("../Graphics/Spy-icon.png", UriKind.Relative)),
729 Width = 16,
730 Height = 16
731 }
732 });
733 }
734
735 if (this.CanChat)
736 {
737 this.GroupSeparator(ref CurrentGroup, "Communication", Menu);
738 Menu.Items.Add(new MenuItem()
739 {
740 Header = "C_hat...",
741 IsEnabled = true,
742 Command = MainWindow.Chat,
743 Icon = new Image()
744 {
745 Source = XmppAccountNode.chatBubble,
746 Width = 16,
747 Height = 16
748 }
749 });
750 }
751
752 if (this.CanReadSensorData)
753 {
754 this.GroupSeparator(ref CurrentGroup, "Communication", Menu);
755 Menu.Items.Add(new MenuItem()
756 {
757 Header = "Read _Momentary Values...",
758 IsEnabled = true,
759 Command = MainWindow.ReadMomentary,
760 Icon = new Image()
761 {
762 Source = new BitmapImage(new Uri("../Graphics/history_16_h.png", UriKind.Relative)),
763 Width = 16,
764 Height = 16
765 }
766 });
767
768 Menu.Items.Add(new MenuItem()
769 {
770 Header = "Read _Detailed Values...",
771 IsEnabled = true,
772 Command = MainWindow.ReadDetailed,
773 Icon = new Image()
774 {
775 Source = new BitmapImage(new Uri("../Graphics/print_preview_lined_16_h.png", UriKind.Relative)),
776 Width = 16,
777 Height = 16
778 }
779 });
780 }
781
782 if (this.CanSubscribeToSensorData)
783 {
784 this.GroupSeparator(ref CurrentGroup, "Communication", Menu);
785 Menu.Items.Add(new MenuItem()
786 {
787 Header = "Su_bscribe to Momentary Values...",
788 IsEnabled = true,
789 Command = MainWindow.SubscribeToMomentary,
790 Icon = new Image()
791 {
792 Source = new BitmapImage(new Uri("../Graphics/rss-feed-icon_16.png", UriKind.Relative)),
793 Width = 16,
794 Height = 16
795 }
796 });
797 }
798
799 if (this.CanConfigure)
800 {
801 this.GroupSeparator(ref CurrentGroup, "Communication", Menu);
802 Menu.Items.Add(new MenuItem()
803 {
804 Header = "Configure _Parameters...",
805 IsEnabled = true,
806 Command = MainWindow.Configure,
807 Icon = new Image()
808 {
809 Source = new BitmapImage(new Uri("../Graphics/Settings-icon_16.png", UriKind.Relative)),
810 Width = 16,
811 Height = 16
812 }
813 });
814 }
815
816 if (this.CanSearch)
817 {
818 this.GroupSeparator(ref CurrentGroup, "Database", Menu);
819 Menu.Items.Add(new MenuItem()
820 {
821 Header = "_Search",
822 IsEnabled = true,
823 Command = MainWindow.Search,
824 Icon = new Image()
825 {
826 Source = new BitmapImage(new Uri("../Graphics/search_16_h.png", UriKind.Relative)),
827 Width = 16,
828 Height = 16
829 }
830 });
831 }
832
833 TreeNode Loop = this;
834 while (!(Loop is null))
835 {
836 if (Loop is IMenuAggregator MenuAggregator)
837 MenuAggregator.AddContexMenuItems(this, ref CurrentGroup, Menu);
838
839 Loop = Loop.parent;
840 }
841 }
842
843 protected void GroupSeparator(ref string CurrentGroup, string Group, ContextMenu Menu)
844 {
845 if (CurrentGroup != Group)
846 {
847 if (!string.IsNullOrEmpty(CurrentGroup))
848 Menu.Items.Add(new MenuItem());
849
850 CurrentGroup = Group;
851 }
852 }
853
857 public virtual void SelectionChanged()
858 {
859 // Do nothing by default.
860 }
861
865 public virtual void ViewClosed()
866 {
867 // Do nothing by default.
868 }
869
870 }
871}
Interaction logic for xaml
Abstract base class for selectable items.
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:24
virtual void OnCollapsed()
Raises the Collapsed event.
Definition: TreeNode.cs:330
virtual void UnloadChildren()
Method is called to notify children can be unloaded.
Definition: TreeNode.cs:302
virtual void UnloadGrandchildren()
Method is called to notify grandchildren can be unloaded.
Definition: TreeNode.cs:310
virtual bool CanCopy
If node can be copied to clipboard.
Definition: TreeNode.cs:399
TreeNode[] Children
Children of the node. If null, children are not loaded.
Definition: TreeNode.cs:72
virtual void Added(MainWindow Window)
Is called when the node has been added to the main window.
Definition: TreeNode.cs:528
virtual Visibility ImageResource2Visibility
If the second image resource is visible or not.
Definition: TreeNode.cs:167
virtual Task GetConfigurationForm(EventHandlerAsync< DataFormEventArgs > Callback, object State)
Gets the configuration form for the node.
Definition: TreeNode.cs:606
virtual void Copy()
Is called when the user wants to copy the node to the clipboard.
Definition: TreeNode.cs:407
abstract ImageSource ImageResource
Image resource for the node.
Definition: TreeNode.cs:143
virtual void Removed(MainWindow Window)
Is called when the node has been removed from the main window.
Definition: TreeNode.cs:536
virtual void Add()
Is called when the user wants to add a node to the current node.
Definition: TreeNode.cs:348
object Tag
Object tagged to the node.
Definition: TreeNode.cs:113
virtual void Edit()
Is called when the user wants to edit a node.
Definition: TreeNode.cs:390
virtual void AddContexMenuItems(ref string CurrentGroup, ContextMenu Menu)
Adds context sensitive menu items to a context menu.
Definition: TreeNode.cs:632
virtual bool CanChat
If it's possible to chat with the node.
Definition: TreeNode.cs:509
virtual Task< SensorDataSubscriptionRequest > SubscribeSensorDataMomentaryReadout(FieldSubscriptionRule[] Rules)
Starts subscription of momentary sensor data values.
Definition: TreeNode.cs:573
virtual bool CanConfigure
If it's possible to configure control parameters on the node.
Definition: TreeNode.cs:581
abstract bool CanRecycle
If the node can be recycled.
Definition: TreeNode.cs:433
virtual DisplayableParameters DisplayableParameters
Gets available displayable parameters.
Definition: TreeNode.cs:214
abstract bool CanDelete
If the node can be deleted.
Definition: TreeNode.cs:357
virtual void LoadSiblings()
Method is called to make sure siblings are loaded.
Definition: TreeNode.cs:322
virtual Task< SensorDataClientRequest > StartSensorDataMomentaryReadout()
Starts readout of momentary sensor data values.
Definition: TreeNode.cs:554
virtual void Search()
Performs a search on the node.
Definition: TreeNode.cs:622
abstract bool CanAddChildren
If children can be added to the node.
Definition: TreeNode.cs:340
virtual void SelectionChanged()
Method called when selection has been changed.
Definition: TreeNode.cs:857
virtual Task SendChatMessage(string Message, string ThreadId, MarkdownDocument Markdown)
Sends a chat message.
Definition: TreeNode.cs:518
EventHandler Collapsed
Event raised when the node has been collapsed.
Definition: TreeNode.cs:257
abstract string Key
Key in parent child collection.
Definition: TreeNode.cs:44
virtual bool CanPaste
If node can be pasted to, from the clipboard.
Definition: TreeNode.cs:416
TreeNode Parent
Parent node. May be null if a root node.
Definition: TreeNode.cs:107
bool? HasChildren
If the node has child nodes or not. If null, the state is undefined, and might need to be checked by ...
Definition: TreeNode.cs:53
virtual ImageSource ImageResource2
Secondary image resource for the node.
Definition: TreeNode.cs:159
bool TryGetChild(string ChildKey, out TreeNode Child)
Tries to get the child node corresponding to a given key.
Definition: TreeNode.cs:96
virtual void AddSniffer(ISniffer Sniffer)
Adds a sniffer to the node.
Definition: TreeNode.cs:490
EventHandler Expanded
Event raised when the node has been expanded.
Definition: TreeNode.cs:252
virtual bool CanSearch
If it's possible to search for data on the node.
Definition: TreeNode.cs:615
virtual Task< SensorDataClientRequest > StartSensorDataFullReadout()
Starts readout of all sensor data values.
Definition: TreeNode.cs:563
virtual void Paste()
Is called when the user wants to paste data from the clipboard to the node.
Definition: TreeNode.cs:424
virtual void OnExpanded()
Raises the Expanded event.
Definition: TreeNode.cs:262
abstract string Header
Tree Node header text.
Definition: TreeNode.cs:122
virtual bool IsSniffable
If the node can be sniffed.
Definition: TreeNode.cs:481
virtual Task Recycle(MainWindow Window)
Is called when the user wants to recycle the node.
Definition: TreeNode.cs:442
virtual void ViewClosed()
Method called when the view has been closed.
Definition: TreeNode.cs:865
abstract string TypeName
Node Type Name.
Definition: TreeNode.cs:183
abstract string ToolTip
Tool Tip for node.
Definition: TreeNode.cs:175
TreeNode(TreeNode Parent)
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:35
virtual void OnUpdated()
Raises the Updated event.
Definition: TreeNode.cs:224
virtual bool CustomDeleteQuestion
If the node provides a custom delete question.
Definition: TreeNode.cs:364
virtual Visibility ImageResourceVisibility
If the second image resource is visible or not.
Definition: TreeNode.cs:151
override void OnSelected()
Raises the Selected event.
Definition: TreeNode.cs:271
EventHandler Updated
Raised when the node has been updated. The sender argument will contain a reference to the node.
Definition: TreeNode.cs:219
virtual bool CanSubscribeToSensorData
If it's possible to subscribe to sensor data from the node.
Definition: TreeNode.cs:548
virtual void LoadChildren()
Method is called to make sure children are loaded.
Definition: TreeNode.cs:294
virtual bool CanReadSensorData
If it's possible to read sensor data from the node.
Definition: TreeNode.cs:543
abstract void Write(XmlWriter Output)
Saves the object to a file.
virtual bool RemoveChild(TreeNode Node)
Removes a child node.
Definition: TreeNode.cs:452
bool IsExpanded
If the node is expanded.
Definition: TreeNode.cs:233
abstract bool CanEdit
If the node can be edited.
Definition: TreeNode.cs:382
virtual Task< bool > RemoveSniffer(ISniffer Sniffer)
Removes a sniffer from the node.
Definition: TreeNode.cs:501
virtual void Dispose()
Disposes of the node and its resources.
Definition: TreeNode.cs:129
virtual void Configure()
Starts configuration of the node.
Definition: TreeNode.cs:586
virtual Task Delete(TreeNode Parent, EventHandler OnDeleted)
Method called when a node is to be deleted.
Definition: TreeNode.cs:371
Class representing a normal XMPP account.
Contains a markdown document. This markdown document class supports original markdown,...
Maintains the status of a field subscription rule.
Contains information about a message logged on a node.
Definition: Message.cs:32
Base class for all node parameters.
Definition: Parameter.cs:10
Interface for nodes that can aggregate items in menues to descendant nodes.
Interface for sniffers. Sniffers can be added to ICommunicationLayer classes to eavesdrop on communic...
Definition: ISniffer.cs:11