Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ConnectionView.xaml.cs
1using System;
2using System.IO;
3using System.Collections.Generic;
4using System.Xml;
5using System.Windows;
6using System.Windows.Controls;
7using System.Windows.Data;
8using System.Windows.Input;
9using Microsoft.Win32;
14using Waher.Events;
17using System.Threading.Tasks;
18
20{
24 public partial class ConnectionView : UserControl, ITabView
25 {
26 private string fileName = string.Empty;
27 private Connections connections;
28 private TreeNode selectedNode = null;
29
30 public ConnectionView()
31 {
33 }
34
35 public void Load(MainWindow Owner)
36 {
37 this.connections = new Connections(Owner);
38 }
39
40 public void Dispose()
41 {
42 this.connections.New();
43 }
44
46 {
47 get { return MainWindow.FindWindow(this); }
48 }
49
50 public Connections Connections => this.connections;
51
52 public string FileName
53 {
54 get => this.fileName;
55 set
56 {
57 this.fileName = value;
58 if (string.IsNullOrEmpty(this.fileName))
59 this.MainWindow.Title = MainWindow.WindowTitle;
60 else
61 this.MainWindow.Title = this.fileName + " - " + MainWindow.WindowTitle;
62 }
63 }
64
65 private void ConnectionTree_SelectedItemChanged(object Sender, RoutedPropertyChangedEventArgs<object> e)
66 {
67 this.ConnectionListView.Items.Clear();
68
69 if (this.ConnectionListView.View is GridView GridView)
70 {
71 while (GridView.Columns.Count > 2)
72 GridView.Columns.RemoveAt(2);
73 }
74 else
75 GridView = null;
76
77 this.selectedNode = this.ConnectionTree.SelectedItem as TreeNode;
78 if (!(this.selectedNode is null))
79 {
80 TreeNode[] Children = this.selectedNode.Children;
81 Dictionary<string, bool> Headers = null;
82 DisplayableParameters Parameters;
83
84 if (!(Children is null))
85 {
86 foreach (TreeNode Child in this.selectedNode.Children)
87 {
88 this.ConnectionListView.Items.Add(Child);
89
90 if (!(GridView is null))
91 {
92 Parameters = Child.DisplayableParameters;
93 if (!(Parameters is null))
94 {
95 foreach (Parameter P in Parameters.Ordered)
96 {
97 if (P.Id == "NodeId" || P.Id == "Type")
98 continue;
99
100 if (Headers is null)
101 Headers = new Dictionary<string, bool>();
102
103 if (!Headers.ContainsKey(P.Id))
104 {
105 Headers[P.Id] = true;
106
107 GridViewColumn Column = new GridViewColumn()
108 {
109 Header = P.Name,
110 Width = double.NaN,
111 DisplayMemberBinding = new Binding("DisplayableParameters[" + P.Id + "]")
112 };
113
114 GridView.Columns.Add(Column);
115 }
116 }
117 }
118 }
119 }
120 }
121 }
122
123 MainWindow MainWindow = MainWindow.FindWindow(this);
124 MainWindow?.SelectionChanged();
125 }
126
127 public bool SaveFile()
128 {
129 if (string.IsNullOrEmpty(this.fileName))
130 return this.SaveNewFile();
131 else
132 {
133 this.connections.Save(this.fileName);
134 return true;
135 }
136 }
137
138 public bool CheckSaved()
139 {
140 if (this.connections.Modified)
141 {
142 switch (MessageBox.Show(MainWindow.FindWindow(this), "You have unsaved changes. Do you want to save these changes before closing the application?",
143 "Save unsaved changes?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question))
144 {
145 case MessageBoxResult.Yes:
146 if (this.SaveFile())
147 break;
148 else
149 return false;
150
151 case MessageBoxResult.No:
152 break;
153
154 case MessageBoxResult.Cancel:
155 return false;
156 }
157 }
158
159 return true;
160 }
161
162 public bool SaveNewFile()
163 {
164 SaveFileDialog Dialog = new SaveFileDialog()
165 {
166 AddExtension = true,
167 CheckPathExists = true,
168 CreatePrompt = false,
169 DefaultExt = "xml",
170 Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
171 Title = "Save connection file"
172 };
173
174 bool? Result = Dialog.ShowDialog(MainWindow.FindWindow(this));
175
176 if (Result.HasValue && Result.Value)
177 {
178 this.FileName = Dialog.FileName;
179 this.SaveFile();
180 return true;
181 }
182 else
183 return false;
184 }
185
186 public async Task Load(string FileName)
187 {
188 try
189 {
190 XmlDocument Xml = new XmlDocument()
191 {
192 PreserveWhitespace = true
193 };
194 Xml.Load(FileName);
195
196 switch (Xml.DocumentElement.LocalName)
197 {
198 case "ClientConnections":
199 this.connections.Load(FileName, Xml);
200 this.FileName = FileName;
201
202 this.ConnectionTree.Items.Clear();
203 foreach (TreeNode Node in this.connections.RootNodes)
204 this.AddNode(Node);
205 break;
206
207 case "Sniff":
208 TabItem TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
209 this.MainWindow.Tabs.Items.Add(TabItem);
210
211 SnifferView SnifferView = new SnifferView(null, null, true);
212 TabItem.Content = SnifferView;
213
214 SnifferView.Sniffer = new TabSniffer(SnifferView);
215
216 this.MainWindow.Tabs.SelectedItem = TabItem;
217
218 SnifferView.Load(Xml, FileName);
219 break;
220
221 case "Chat":
222 TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
223 this.MainWindow.Tabs.Items.Add(TabItem);
224
225 bool Muc = XML.Attribute(Xml.DocumentElement, "muc", false);
226 ChatView ChatView = new ChatView(null, Muc);
227 ChatView.Input.IsEnabled = false;
228 ChatView.SendButton.IsEnabled = false;
229
230 TabItem.Content = ChatView;
231
232 this.MainWindow.Tabs.SelectedItem = TabItem;
233
234 await ChatView.Load(Xml, FileName);
235 break;
236
237 case "SensorData":
238 TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
239 this.MainWindow.Tabs.Items.Add(TabItem);
240
241 SensorDataView SensorDataView = new SensorDataView(null, null, false);
242 TabItem.Content = SensorDataView;
243
244 this.MainWindow.Tabs.SelectedItem = TabItem;
245
246 SensorDataView.Load(Xml, FileName);
247 break;
248
249 case "SearchResult":
250 TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
251 this.MainWindow.Tabs.Items.Add(TabItem);
252
254 TabItem.Content = SearchResultView;
255
256 this.MainWindow.Tabs.SelectedItem = TabItem;
257
258 SearchResultView.Load(Xml, FileName);
259 break;
260
261 case "Script":
262 TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
263 this.MainWindow.Tabs.Items.Add(TabItem);
264
266 TabItem.Content = ScriptView;
267
268 this.MainWindow.Tabs.SelectedItem = TabItem;
269
270 ScriptView.Load(Xml, FileName);
271 break;
272
273 case "EventOutput":
274 TabItem = MainWindow.NewTab(Path.GetFileName(FileName));
275 this.MainWindow.Tabs.Items.Add(TabItem);
276
277 LogView LogView = new LogView(null, false);
278 TabItem.Content = LogView;
279
280 this.MainWindow.Tabs.SelectedItem = TabItem;
281
282 LogView.Load(Xml, FileName);
283 break;
284
285 case "Report":
286 TabItem = MainWindow.NewTab(Path.GetFileName(FileName), out TextBlock HeaderLabel);
287 this.MainWindow.Tabs.Items.Add(TabItem);
288
289 QueryResultView ReportView = await QueryResultView.CreateAsync(null, null, HeaderLabel);
290 TabItem.Content = ReportView;
291
292 this.MainWindow.Tabs.SelectedItem = TabItem;
293
294 ReportView.Load(Xml, FileName);
295 break;
296
297 default:
298 throw new Exception("Unrecognized file format.");
299 }
300 }
301 catch (Exception ex)
302 {
303 ex = Log.UnnestException(ex);
304 MessageBox.Show(ex.Message, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
305 }
306 }
307
308 public void NewButton_Click(object Sender, RoutedEventArgs e)
309 {
310 if (!this.CheckSaved())
311 return;
312
313 this.ConnectionTree.Items.Clear();
314 this.connections.New();
315 this.FileName = string.Empty;
316 }
317
318 public void SaveButton_Click(object Sender, RoutedEventArgs e)
319 {
320 this.SaveFile();
321 }
322
323 public void SaveAsButton_Click(object Sender, RoutedEventArgs e)
324 {
325 this.SaveNewFile();
326 }
327
328 public async void OpenButton_Click(object Sender, RoutedEventArgs e)
329 {
330 try
331 {
332 if (!this.CheckSaved())
333 return;
334
335 OpenFileDialog Dialog = new OpenFileDialog()
336 {
337 AddExtension = true,
338 CheckFileExists = true,
339 CheckPathExists = true,
340 DefaultExt = "xml",
341 Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
342 Multiselect = false,
343 ShowReadOnly = true,
344 Title = "Open connection file"
345 };
346
347 bool? Result = Dialog.ShowDialog(MainWindow.FindWindow(this));
348
349 if (Result.HasValue && Result.Value)
350 await this.Load(Dialog.FileName);
351 }
352 catch (Exception ex)
353 {
354 ex = Log.UnnestException(ex);
355 MessageBox.Show(ex.Message, "Unable to load file.", MessageBoxButton.OK, MessageBoxImage.Error);
356 }
357 }
358
359 public void ConnectTo_Executed(object Sender, ExecutedRoutedEventArgs e)
360 {
361 ConnectToForm Dialog = new ConnectToForm()
362 {
363 Owner = this.MainWindow
364 };
365 bool? Result = Dialog.ShowDialog();
366
367 if (Result.HasValue && Result.Value)
368 {
369 if (!int.TryParse(Dialog.XmppPort.Text, out int Port))
371
372 XmppAccountNode Node = new XmppAccountNode(this.connections, null, Dialog.XmppServer.Text,
373 (TransportMethod)Dialog.ConnectionMethod.SelectedIndex, Port, Dialog.UrlEndpoint.Text,
374 Dialog.AccountName.Text, Dialog.PasswordHash, Dialog.PasswordHashMethod,
375 Dialog.TrustServerCertificate.IsChecked.HasValue && Dialog.TrustServerCertificate.IsChecked.Value,
376 Dialog.AllowInsecureAuthentication.IsChecked.HasValue && Dialog.AllowInsecureAuthentication.IsChecked.Value);
377
378 this.connections.Add(Node);
379 this.AddNode(Node);
380 }
381 }
382
383 private void AddNode(TreeNode Node)
384 {
385 this.ConnectionTree.Items.Add(Node);
386 this.NodeAdded(null, Node);
387 }
388
389 public void NodeAdded(TreeNode _, TreeNode ChildNode)
390 {
391 ChildNode.Updated += this.Node_Updated;
392 ChildNode.Added(this.MainWindow);
393 }
394
395 public void NodeRemoved(TreeNode Parent, TreeNode ChildNode)
396 {
397 ChildNode.Updated -= this.Node_Updated;
398 ChildNode.Removed(this.MainWindow);
399
400 if (Parent is null)
401 {
402 this.connections.Delete(ChildNode);
403 MainWindow.UpdateGui(() =>
404 {
405 this.ConnectionTree.Items.Remove(ChildNode);
406 return Task.CompletedTask;
407 });
408 }
409 else
410 Parent.RemoveChild(ChildNode);
411
412 this.Node_Updated(this, EventArgs.Empty);
413 }
414
415 private void Node_Updated(object Sender, EventArgs e)
416 {
417 if (this.refreshTimer > DateTime.MinValue)
418 {
419 MainWindow.Scheduler?.Remove(this.refreshTimer);
420 this.refreshTimer = DateTime.MinValue;
421 }
422
423 this.refreshTimer = MainWindow.Scheduler.Add(DateTime.Now.AddMilliseconds(250), this.RefreshTree, null);
424 }
425
426 public void ShowStatus(string Message)
427 {
428 if (this.status == Message)
429 return;
430
431 this.status = Message;
432
433 if (this.statusTimer > DateTime.MinValue)
434 {
435 MainWindow.Scheduler?.Remove(this.statusTimer);
436 this.statusTimer = DateTime.MinValue;
437 }
438
439 this.statusTimer = MainWindow.Scheduler.Add(DateTime.Now.AddMilliseconds(250), this.SetStatus, null);
440 }
441
442 private string status = string.Empty;
443 private DateTime refreshTimer = DateTime.MinValue;
444 private DateTime statusTimer = DateTime.MinValue;
445
446 private void RefreshTree(object _)
447 {
448 if (this.statusTimer > DateTime.MinValue)
449 {
450 MainWindow.Scheduler?.Remove(this.statusTimer);
451 this.statusTimer = DateTime.MinValue;
452 }
453
454 MainWindow.UpdateGui(() =>
455 {
456 this.ConnectionTree.Items.Refresh();
457 return Task.CompletedTask;
458 });
459 }
460
461 private void SetStatus(object _)
462 {
463 if (this.statusTimer > DateTime.MinValue)
464 {
465 MainWindow.Scheduler?.Remove(this.statusTimer);
466 this.statusTimer = DateTime.MinValue;
467 }
468
469 MainWindow.UpdateGui(() =>
470 {
471 this.ConnectionStatus.Content = this.status;
472 return Task.CompletedTask;
473 });
474 }
475
476 private void ConnectionListView_SelectionChanged(object Sender, SelectionChangedEventArgs e)
477 {
478 this.ConnectionListView_GotFocus(Sender, e);
479 }
480
481 public TreeNode SelectedNode => this.selectedNode;
482
483 private void TreeContextMenu_ContextMenuOpening(object Sender, ContextMenuEventArgs e)
484 {
485 this.PopulateConextMenu(this.TreeContextMenu);
486 }
487
488 private void ListViewContextMenu_ContextMenuOpening(object Sender, ContextMenuEventArgs e)
489 {
490 this.PopulateConextMenu(this.ListViewContextMenu);
491 }
492
493 private void PopulateConextMenu(ContextMenu Menu)
494 {
495 string Group = string.Empty;
496
497 Menu.Items.Clear();
498
499 this.selectedNode?.AddContexMenuItems(ref Group, Menu);
500 }
501
502 private void ConnectionListView_GotFocus(object Sender, RoutedEventArgs e)
503 {
504 this.selectedNode = this.ConnectionListView.SelectedItem as TreeNode;
505
506 MainWindow MainWindow = MainWindow.FindWindow(this);
507 MainWindow?.SelectionChanged();
508 }
509
510 private void ConnectionTree_GotFocus(object Sender, RoutedEventArgs e)
511 {
512 this.selectedNode = this.ConnectionTree.SelectedItem as TreeNode;
513
514 MainWindow MainWindow = MainWindow.FindWindow(this);
515 MainWindow?.SelectionChanged();
516 }
517
518 }
519}
Interaction logic for ChatView.xaml
Interaction logic for ConnectionView.xaml
void InitializeComponent()
InitializeComponent
Interaction logic for LogView.xaml
Definition: LogView.xaml.cs:23
Interaction logic for QueryResultView.xaml
Interaction logic for ScriptView.xaml
Interaction logic for SensorDataView.xaml
Interaction logic for SensorDataView.xaml
Interaction logic for SnifferView.xaml
Interaction logic for ConnectToForm.xaml
string PasswordHash
Password hash of a successfully authenticated client.
string PasswordHashMethod
Password hash method of a successfully authenticated client.
Interaction logic for xaml
Maintains the set of open connections.
Definition: Connections.cs:15
void Save(string FileName)
Saves connections to an XML file.
Definition: Connections.cs:101
bool Delete(TreeNode RootNode)
Deletes a new connection.
Definition: Connections.cs:55
void Load(string FileName)
Loads the environment from an XML file.
Definition: Connections.cs:127
void New()
Creates a new environment.
Definition: Connections.cs:167
void Add(TreeNode RootNode)
Adds a new connection.
Definition: Connections.cs:41
TreeNode[] RootNodes
Available root nodes.
Definition: Connections.cs:185
bool Modified
If the source has been changed.
Definition: Connections.cs:92
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:24
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 void Removed(MainWindow Window)
Is called when the node has been removed from the main window.
Definition: TreeNode.cs:536
virtual void AddContexMenuItems(ref string CurrentGroup, ContextMenu Menu)
Adds context sensitive menu items to a context menu.
Definition: TreeNode.cs:632
virtual DisplayableParameters DisplayableParameters
Gets available displayable parameters.
Definition: TreeNode.cs:214
virtual bool RemoveChild(TreeNode Node)
Removes a child node.
Definition: TreeNode.cs:452
Class representing a normal XMPP account.
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 Exception UnnestException(Exception Exception)
Unnests an exception, to extract the relevant inner exception.
Definition: Log.cs:818
Class containing credentials for an XMPP client connection.
const int DefaultPort
Default XMPP Server port.
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 tab view user controls in the client.
Definition: ITabView.cs:10