Horizon – Diff between revs 11 and 12
?pathlinks?
Rev 11 | Rev 12 | |||
---|---|---|---|---|
Line 4... | Line 4... | |||
4 | using System.ComponentModel; |
4 | using System.ComponentModel; |
|
5 | using System.Data.SQLite; |
5 | using System.Data.SQLite; |
|
6 | using System.Diagnostics; |
6 | using System.Diagnostics; |
|
7 | using System.Drawing; |
7 | using System.Drawing; |
|
8 | using System.IO; |
8 | using System.IO; |
|
- | 9 | using System.IO.Ports; |
||
9 | using System.Linq; |
10 | using System.Linq; |
|
- | 11 | using System.Net.Sockets; |
||
10 | using System.Security.Cryptography; |
12 | using System.Security.Cryptography; |
|
- | 13 | using System.Text; |
||
11 | using System.Threading; |
14 | using System.Threading; |
|
12 | using System.Threading.Tasks; |
15 | using System.Threading.Tasks; |
|
13 | using System.Windows.Forms; |
16 | using System.Windows.Forms; |
|
14 | using Horizon.Database; |
17 | using Horizon.Database; |
|
15 | using Horizon.Utilities; |
18 | using Horizon.Utilities; |
|
16 | using Microsoft.WindowsAPICodePack.Dialogs; |
19 | using Microsoft.WindowsAPICodePack.Dialogs; |
|
- | 20 | using Mono.Zeroconf; |
||
- | 21 | using Mono.Zeroconf.Providers.Bonjour; |
||
- | 22 | using Newtonsoft.Json; |
||
17 | using Org.BouncyCastle.Crypto; |
23 | using Org.BouncyCastle.Crypto; |
|
- | 24 | using Org.BouncyCastle.Utilities.Net; |
||
18 | using Serilog; |
25 | using Serilog; |
|
- | 26 | using WatsonTcp; |
||
Line 19... | Line 27... | |||
19 | |
27 | |
|
20 | namespace Horizon.Snapshots |
28 | namespace Horizon.Snapshots |
|
21 | { |
29 | { |
|
22 | public partial class SnapshotManagerForm : Form |
30 | public partial class SnapshotManagerForm : Form |
|
Line 53... | Line 61... | |||
53 | |
61 | |
|
Line 54... | Line 62... | |||
54 | private readonly CancellationTokenSource _localCancellationTokenSource; |
62 | private readonly CancellationTokenSource _localCancellationTokenSource; |
|
Line -... | Line 63... | |||
- | 63 | |
||
- | 64 | private readonly CancellationToken _localCancellationToken; |
||
- | 65 | |
||
- | 66 | private readonly Mono.Zeroconf.ServiceBrowser _horizonServiceBrowser; |
||
- | 67 | |
||
- | 68 | private IResolvableService _resolvedService; |
||
55 | |
69 | |
|
Line 56... | Line 70... | |||
56 | private readonly CancellationToken _localCancellationToken; |
70 | private readonly ConcurrentDictionary<string, Service> _discoveredHorizonNetworkShares; |
|
Line 57... | Line 71... | |||
57 | |
71 | |
|
Line 67... | Line 81... | |||
67 | |
81 | |
|
Line 68... | Line 82... | |||
68 | _searchTextBoxChangedContinuation = new ScheduledContinuation(); |
82 | _searchTextBoxChangedContinuation = new ScheduledContinuation(); |
|
69 | |
83 | |
|
- | 84 | _localCancellationTokenSource = new CancellationTokenSource(); |
||
- | 85 | _localCancellationToken = _localCancellationTokenSource.Token; |
||
- | 86 | |
||
- | 87 | _discoveredHorizonNetworkShares = new ConcurrentDictionary<string, Service>(); |
||
70 | _localCancellationTokenSource = new CancellationTokenSource(); |
88 | _horizonServiceBrowser = new Mono.Zeroconf.ServiceBrowser(); |
|
Line 71... | Line 89... | |||
71 | _localCancellationToken = _localCancellationTokenSource.Token; |
89 | _horizonServiceBrowser.ServiceAdded += OnHorizonServiceBrowserOnServiceAdded; |
|
72 | } |
90 | } |
|
73 | |
91 | |
|
Line 94... | Line 112... | |||
94 | components.Dispose(); |
112 | components.Dispose(); |
|
95 | } |
113 | } |
|
Line 96... | Line 114... | |||
96 | |
114 | |
|
Line -... | Line 115... | |||
- | 115 | _snapshotDatabase.SnapshotCreate -= SnapshotManager_SnapshotCreate; |
||
- | 116 | |
||
97 | _snapshotDatabase.SnapshotCreate -= SnapshotManager_SnapshotCreate; |
117 | _horizonServiceBrowser.ServiceAdded -= OnHorizonServiceBrowserOnServiceAdded; |
|
Line 98... | Line 118... | |||
98 | |
118 | _horizonServiceBrowser.Dispose(); |
|
99 | _localCancellationTokenSource.Cancel(); |
119 | _localCancellationTokenSource.Cancel(); |
|
Line 100... | Line 120... | |||
100 | |
120 | |
|
Line 101... | Line 121... | |||
101 | base.Dispose(disposing); |
121 | base.Dispose(disposing); |
|
- | 122 | } |
||
- | 123 | |
||
- | 124 | #endregion |
||
- | 125 | |
||
- | 126 | #region Event Handlers |
||
- | 127 | private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) |
||
- | 128 | { |
||
- | 129 | |
||
- | 130 | } |
||
- | 131 | |
||
102 | } |
132 | private void contextMenuStrip1_Opened(object sender, EventArgs e) |
|
103 | |
133 | { |
|
104 | #endregion |
134 | _horizonServiceBrowser.Browse("_horizon._tcp", "local"); |
|
Line 105... | Line 135... | |||
105 | |
135 | } |
|
Line 586... | Line 616... | |||
586 | }); |
616 | }); |
|
587 | } |
617 | } |
|
Line 588... | Line 618... | |||
588 | |
618 | |
|
589 | private async void SnapshotManagerForm_Load(object sender, EventArgs e) |
619 | private async void SnapshotManagerForm_Load(object sender, EventArgs e) |
|
- | 620 | { |
||
- | 621 | // Start browsing for network services. |
||
- | 622 | _horizonServiceBrowser.Browse("_horizon._tcp", "local"); |
||
- | 623 | |
||
590 | { |
624 | // Load snapshots. |
|
591 | toolStripProgressBar1.Minimum = 0; |
625 | toolStripProgressBar1.Minimum = 0; |
|
Line 592... | Line 626... | |||
592 | toolStripProgressBar1.Maximum = (int)await _snapshotDatabase.CountSnapshotsAsync(_cancellationToken); |
626 | toolStripProgressBar1.Maximum = (int)await _snapshotDatabase.CountSnapshotsAsync(_cancellationToken); |
|
Line 645... | Line 679... | |||
645 | |
679 | |
|
646 | Log.Error(exception, "Unable to load snapshots."); |
680 | Log.Error(exception, "Unable to load snapshots."); |
|
647 | } |
681 | } |
|
Line -... | Line 682... | |||
- | 682 | } |
||
- | 683 | |
||
- | 684 | private void OnHorizonServiceBrowserOnServiceAdded(object o, Mono.Zeroconf.ServiceBrowseEventArgs args) |
||
- | 685 | { |
||
- | 686 | _resolvedService = args.Service; |
||
- | 687 | |
||
- | 688 | Log.Information("Found Service: {0}", _resolvedService.Name); |
||
- | 689 | |
||
- | 690 | _resolvedService.Resolved += OnServiceOnResolved; |
||
- | 691 | |
||
- | 692 | _resolvedService.Resolve(); |
||
- | 693 | |
||
- | 694 | _resolvedService.Resolved -= OnServiceOnResolved; |
||
- | 695 | } |
||
- | 696 | |
||
- | 697 | private void OnServiceOnResolved(object o, ServiceResolvedEventArgs args) |
||
- | 698 | { |
||
- | 699 | var service = (Service) args.Service; |
||
- | 700 | |
||
- | 701 | Log.Information("Resolved Service: {0} - {1}:{2} ({3} TXT record entries)", service.FullName, service.HostEntry.AddressList[0], service.UPort, service.TxtRecord.Count); |
||
- | 702 | |
||
- | 703 | _discoveredHorizonNetworkShares.TryAdd(service.Name, service); |
||
- | 704 | |
||
- | 705 | var discoveredServiceMenuItem = new ToolStripMenuItem(service.Name, null, OnShareWithNodeClicked); |
||
- | 706 | discoveredServiceMenuItem.Tag = service; |
||
- | 707 | |
||
- | 708 | shareToToolStripMenuItem.DropDownItems.Add(discoveredServiceMenuItem); |
||
- | 709 | } |
||
- | 710 | |
||
- | 711 | private async void OnShareWithNodeClicked(object sender, EventArgs e) |
||
- | 712 | { |
||
- | 713 | var toolStripMenuItem = (ToolStripMenuItem)sender; |
||
- | 714 | |
||
- | 715 | var service = (Service)toolStripMenuItem.Tag; |
||
- | 716 | |
||
- | 717 | var rows = GetSelectedDataGridViewRows(dataGridView1); |
||
- | 718 | |
||
- | 719 | var count = rows.Count; |
||
- | 720 | |
||
- | 721 | toolStripProgressBar1.Minimum = 0; |
||
- | 722 | toolStripProgressBar1.Maximum = count; |
||
- | 723 | |
||
- | 724 | var progress = new Progress<DataGridViewRowProgress>(rowProgress => |
||
- | 725 | { |
||
- | 726 | if (rowProgress is DataGridViewRowProgressFailure rowProgressFailure) |
||
- | 727 | { |
||
- | 728 | Log.Error(rowProgressFailure.Exception, "Unable to transfer data."); |
||
- | 729 | |
||
- | 730 | toolStripStatusLabel1.Text = |
||
- | 731 | $"Could not transfer {rowProgress.Row.Cells["NameColumn"].Value}..."; |
||
- | 732 | toolStripProgressBar1.Value = rowProgress.Index + 1; |
||
- | 733 | |
||
- | 734 | statusStrip1.Update(); |
||
- | 735 | |
||
- | 736 | return; |
||
- | 737 | } |
||
- | 738 | |
||
- | 739 | toolStripStatusLabel1.Text = |
||
- | 740 | $"Transferred {rowProgress.Row.Cells["NameColumn"].Value}..."; |
||
- | 741 | toolStripProgressBar1.Value = rowProgress.Index + 1; |
||
- | 742 | |
||
- | 743 | statusStrip1.Update(); |
||
- | 744 | }); |
||
- | 745 | |
||
- | 746 | await Task.Run(() => TransferFiles(rows, service, progress, _cancellationToken), _cancellationToken); |
||
- | 747 | |
||
- | 748 | if (_cancellationToken.IsCancellationRequested) |
||
- | 749 | { |
||
- | 750 | toolStripProgressBar1.Value = toolStripProgressBar1.Maximum; |
||
- | 751 | toolStripStatusLabel1.Text = "Done."; |
||
- | 752 | } |
||
648 | } |
753 | } |
|
649 | |
754 | |
|
650 | private void SnapshotManagerForm_Closing(object sender, FormClosingEventArgs e) |
755 | private void SnapshotManagerForm_Closing(object sender, FormClosingEventArgs e) |
|
Line 651... | Line 756... | |||
651 | { |
756 | { |
|
Line 1305... | Line 1410... | |||
1305 | } |
1410 | } |
|
Line 1306... | Line 1411... | |||
1306 | |
1411 | |
|
Line 1307... | Line 1412... | |||
1307 | #endregion |
1412 | #endregion |
|
- | 1413 | |
||
- | 1414 | #region Private Methods |
||
- | 1415 | private void DataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) |
||
- | 1416 | { |
||
- | 1417 | DataGridView dataGridView = sender as DataGridView; |
||
- | 1418 | foreach (DataGridViewCell cell in dataGridView.Rows[e.RowIndex].Cells) |
||
- | 1419 | { |
||
- | 1420 | if (cell.Selected == false) { continue; } |
||
- | 1421 | var bgColorCell = Color.White; |
||
- | 1422 | if (cell.Style.BackColor != Color.Empty) { bgColorCell = cell.Style.BackColor; } |
||
- | 1423 | else if (cell.InheritedStyle.BackColor != Color.Empty) { bgColorCell = cell.InheritedStyle.BackColor; } |
||
- | 1424 | cell.Style.SelectionBackColor = MixColor(bgColorCell, Color.FromArgb(0, 150, 255), 10, 4); |
||
- | 1425 | } |
||
- | 1426 | } |
||
- | 1427 | |
||
- | 1428 | //Mix two colors |
||
- | 1429 | //Example: Steps=10 & Position=4 makes Color2 mix 40% into Color1 |
||
- | 1430 | /// <summary> |
||
- | 1431 | /// Mix two colors. |
||
- | 1432 | /// </summary> |
||
- | 1433 | /// <param name="Color1"></param> |
||
- | 1434 | /// <param name="Color2"></param> |
||
- | 1435 | /// <param name="Steps"></param> |
||
- | 1436 | /// <param name="Position"></param> |
||
- | 1437 | /// <example>Steps=10 & Positon=4 makes Color2 mix 40% into Color1</example> |
||
- | 1438 | /// <remarks>https://stackoverflow.com/questions/38337849/transparent-selectionbackcolor-for-datagridview-cell</remarks> |
||
- | 1439 | /// <returns></returns> |
||
- | 1440 | public static Color MixColor(Color Color1, Color Color2, int Steps, int Position) |
||
- | 1441 | { |
||
- | 1442 | if (Position <= 0 || Steps <= 1) { return Color1; } |
||
- | 1443 | if (Position >= Steps) { return Color2; } |
||
- | 1444 | return Color.FromArgb( |
||
- | 1445 | Color1.R + ((Color2.R - Color1.R) / Steps * Position), |
||
- | 1446 | Color1.G + ((Color2.G - Color1.G) / Steps * Position), |
||
- | 1447 | Color1.B + ((Color2.B - Color1.B) / Steps * Position) |
||
Line 1308... | Line 1448... | |||
1308 | |
1448 | ); |
|
1309 | #region Private Methods |
1449 | } |
|
1310 | |
1450 | |
|
1311 | private async Task DeleteFiles(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress, |
1451 | private async Task DeleteFiles(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress, |
|
Line 1408... | Line 1548... | |||
1408 | progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception)); |
1548 | progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception)); |
|
1409 | } |
1549 | } |
|
1410 | } |
1550 | } |
|
1411 | } |
1551 | } |
|
Line -... | Line 1552... | |||
- | 1552 | |
||
- | 1553 | |
||
- | 1554 | private async Task TransferFiles(IReadOnlyList<DataGridViewRow> rows, Service service, |
||
- | 1555 | IProgress<DataGridViewRowProgress> progress, CancellationToken cancellationToken) |
||
- | 1556 | { |
||
- | 1557 | |
||
- | 1558 | var client = new WatsonTcpClient($"{service.HostEntry.AddressList[0]}", service.UPort); |
||
- | 1559 | client.Events.MessageReceived += (sender, args) => |
||
- | 1560 | { |
||
- | 1561 | Log.Information($"{args.Data.Length} byte long message received from {args.Client.IpPort}"); |
||
- | 1562 | }; |
||
- | 1563 | |
||
- | 1564 | try |
||
- | 1565 | { |
||
- | 1566 | client.Connect(); |
||
- | 1567 | |
||
- | 1568 | var count = rows.Count; |
||
- | 1569 | |
||
- | 1570 | for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i) |
||
- | 1571 | { |
||
- | 1572 | try |
||
- | 1573 | { |
||
- | 1574 | var completeSnapshot = await _snapshotDatabase.GetCompleteSnapshot((string)rows[i].Cells["HashColumn"].Value, cancellationToken); |
||
- | 1575 | |
||
- | 1576 | var jsonSnapshot = JsonConvert.SerializeObject(completeSnapshot); |
||
- | 1577 | |
||
- | 1578 | await client.SendAsync(jsonSnapshot, null, cancellationToken); |
||
- | 1579 | |
||
- | 1580 | progress.Report(new DataGridViewRowProgressSuccess(rows[i], i)); |
||
- | 1581 | } |
||
- | 1582 | catch (Exception exception) |
||
- | 1583 | { |
||
- | 1584 | progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception)); |
||
- | 1585 | } |
||
- | 1586 | } |
||
- | 1587 | } |
||
- | 1588 | finally |
||
- | 1589 | { |
||
- | 1590 | client.Dispose(); |
||
- | 1591 | } |
||
- | 1592 | |
||
- | 1593 | } |
||
1412 | |
1594 | |
|
1413 | private async Task RevertFile(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress, |
1595 | private async Task RevertFile(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress, |
|
1414 | CancellationToken cancellationToken) |
1596 | CancellationToken cancellationToken) |
|
1415 | { |
1597 | { |
|
Line 1654... | Line 1836... | |||
1654 | } |
1836 | } |
|
1655 | } |
1837 | } |
|
1656 | } |
1838 | } |
|
Line 1657... | Line 1839... | |||
1657 | |
1839 | |
|
1658 | #endregion |
- | ||
1659 | |
- | ||
1660 | private void DataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) |
- | ||
1661 | { |
- | ||
1662 | DataGridView dataGridView = sender as DataGridView; |
- | ||
1663 | foreach (DataGridViewCell cell in dataGridView.Rows[e.RowIndex].Cells) |
- | ||
1664 | { |
- | ||
1665 | if (cell.Selected == false) { continue; } |
- | ||
1666 | var bgColorCell = Color.White; |
- | ||
1667 | if (cell.Style.BackColor != Color.Empty) { bgColorCell = cell.Style.BackColor; } |
- | ||
1668 | else if (cell.InheritedStyle.BackColor != Color.Empty) { bgColorCell = cell.InheritedStyle.BackColor; } |
- | ||
1669 | cell.Style.SelectionBackColor = MixColor(bgColorCell, Color.FromArgb(0, 150, 255), 10, 4); |
- | ||
1670 | } |
- | ||
1671 | } |
- | ||
1672 | |
- | ||
1673 | //Mix two colors |
- | ||
1674 | //Example: Steps=10 & Position=4 makes Color2 mix 40% into Color1 |
- | ||
1675 | /// <summary> |
- | ||
1676 | /// Mix two colors. |
- | ||
1677 | /// </summary> |
- | ||
1678 | /// <param name="Color1"></param> |
- | ||
1679 | /// <param name="Color2"></param> |
- | ||
1680 | /// <param name="Steps"></param> |
- | ||
1681 | /// <param name="Position"></param> |
- | ||
1682 | /// <example>Steps=10 & Positon=4 makes Color2 mix 40% into Color1</example> |
- | ||
1683 | /// <remarks>https://stackoverflow.com/questions/38337849/transparent-selectionbackcolor-for-datagridview-cell</remarks> |
- | ||
1684 | /// <returns></returns> |
- | ||
1685 | public static Color MixColor(Color Color1, Color Color2, int Steps, int Position) |
- | ||
1686 | { |
- | ||
1687 | if (Position <= 0 || Steps <= 1) { return Color1; } |
- | ||
1688 | if (Position >= Steps) { return Color2; } |
- | ||
1689 | return Color.FromArgb( |
- | ||
1690 | Color1.R + ((Color2.R - Color1.R) / Steps * Position), |
- | ||
1691 | Color1.G + ((Color2.G - Color1.G) / Steps * Position), |
- | ||
1692 | Color1.B + ((Color2.B - Color1.B) / Steps * Position) |
- | ||
1693 | ); |
- | ||
1694 | } |
1840 | #endregion |
|
1695 | } |
1841 | } |
|
1696 | } |
1842 | } |