123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.IO;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media.Imaging;
- using System.Windows.Threading;
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Configuration;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using Syncfusion.UI.Xaml.Grid;
- using Syncfusion.UI.Xaml.TreeGrid;
- namespace PRSDesktop
- {
- public enum SVNFileStatus
- {
- Unknown,
- RemoteAddition,
- LocalAddition,
- RemoteModified,
- LocalModified,
- UpToDate
- }
- public class SVNObject : INotifyPropertyChanged
- {
- private static readonly Dictionary<SVNFileStatus, BitmapImage> _images = new()
- {
- { SVNFileStatus.Unknown, Resources.warning.AsBitmapImage() },
- { SVNFileStatus.UpToDate, Resources.tick.AsBitmapImage() },
- { SVNFileStatus.RemoteAddition, Resources.download.AsBitmapImage() },
- { SVNFileStatus.LocalAddition, Resources.upload.AsBitmapImage() },
- { SVNFileStatus.RemoteModified, Resources.remotefile.AsBitmapImage() },
- { SVNFileStatus.LocalModified, Resources.lightbulb.AsBitmapImage() }
- };
- private long _localsize;
- private DateTime _localtime = DateTime.MinValue;
- private readonly SVNObject _parent;
- private long _remotesize;
- private DateTime _remotetime = DateTime.MinValue;
- private SVNFileStatus _status = SVNFileStatus.Unknown;
- public SVNObject(string[] path, string name, SVNObject parent = null)
- {
- ID = Guid.NewGuid();
- _status = SVNFileStatus.Unknown;
- Path = path;
- Name = name;
- _parent = parent;
- }
- public SVNFileStatus Status
- {
- get => _status;
- set
- {
- _status = value;
- NotifyPropertyChanged("Status");
- }
- }
- public BitmapImage Image => _images[Status];
- public Guid ID { get; }
- public Guid ParentID => _parent != null ? _parent.ID : Guid.Empty;
-
-
- public string[] Path { get; }
- public string Name { get; }
- public long RemoteSize
- {
- get => _remotesize;
- set
- {
- _remotesize = value;
- Status = CheckStatus();
- NotifyPropertyChanged("RemoteSize");
- }
- }
- public DateTime RemoteTime
- {
- get => _remotetime;
- set
- {
- _remotetime = value;
- Status = CheckStatus();
- NotifyPropertyChanged("RemoteTime");
- }
- }
- public long LocalSize
- {
- get => _localsize;
- set
- {
- _localsize = value;
- Status = CheckStatus();
- NotifyPropertyChanged("LocalSize");
- }
- }
- public DateTime LocalTime
- {
- get => _localtime;
- set
- {
- _localtime = value;
- Status = CheckStatus();
- NotifyPropertyChanged("LocalTime");
- }
- }
- public string DisplayName => Uri.UnescapeDataString(Name).TrimEnd('/');
- public event PropertyChangedEventHandler PropertyChanged;
- public bool Equals(string[] segments)
- {
- if (segments.Length != Path.Length + 1)
- return false;
- for (var i = 0; i < Path.Length; i++)
- if (!string.Equals(Path[i], segments[i]))
- return false;
- if (!string.Equals(Name, segments.Last()))
- return false;
- return true;
- }
- public override string ToString()
- {
- return string.Format("[{0}].[{1}]", string.Join("].[", Path), Name);
- }
- private SVNFileStatus CheckStatus()
- {
- if (_localtime.IsEmpty())
- return SVNFileStatus.RemoteAddition;
- if (_remotetime.IsEmpty())
- return SVNFileStatus.LocalAddition;
- if (_remotetime > _localtime)
- return SVNFileStatus.RemoteModified;
- if (_localtime > _remotetime)
- return SVNFileStatus.LocalModified;
- return SVNFileStatus.UpToDate;
- }
- public void NotifyPropertyChanged(string propName)
- {
- if (PropertyChanged != null)
- PropertyChanged(this, new PropertyChangedEventArgs(propName));
- }
- }
- public class SVNFolder : SVNObject
- {
- public SVNFolder(string[] path, string name, SVNObject parent = null) : base(path, name, parent)
- {
- }
- }
- public class SVNFile : SVNObject
- {
- public SVNFile(string[] path, string name, SVNObject parent = null) : base(path, name, parent)
- {
- }
- }
- public abstract class SyncEntry
- {
- public Uri Parent { get; set; }
- public Uri Path { get; set; }
- public long Size { get; set; }
- public DateTime Modified { get; set; }
- }
- public class LocalSyncEntry : SyncEntry
- {
- }
- public class RemoteSyncEntry : SyncEntry
- {
- }
- /// <summary>
- /// Interaction logic for JobDocuments.xaml
- /// </summary>
- public partial class JobDocuments : UserControl, IPanel<Job>, IJobControl
- {
- private readonly ObservableCollection<SVNFile> _files = new();
- private readonly ObservableCollection<SVNFolder> _folders = new();
- private readonly string _localroot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "test");
- private Uri _serverroot = new("https://MacOSW10/svn/test/");
- private WaitCursor _waitcursor;
- //private SvnClient svnclient = null;
- private readonly DispatcherTimer _waitcursortimer;
- private string jobnumber = "";
- private Guid lastjobid = Guid.Empty;
- private readonly BackgroundWorker localfiles;
- private readonly BackgroundWorker localfolders;
- private readonly BackgroundWorker remotefiles;
- private readonly BackgroundWorker remotefolders;
- private JobDocumentsScreenSettings settings;
- public JobDocuments()
- {
- InitializeComponent();
- remotefolders = new BackgroundWorker();
- remotefolders.WorkerReportsProgress = true;
- remotefolders.WorkerSupportsCancellation = false;
- //remotefolders.DoWork += RemoteFoldersRefresh;
- remotefolders.ProgressChanged += (o, e) => HandleProgress(e, _folders);
- localfolders = new BackgroundWorker();
- localfolders.WorkerReportsProgress = true;
- localfolders.WorkerSupportsCancellation = false;
- //localfolders.DoWork += LocalFoldersRefresh;
- localfolders.ProgressChanged += (o, e) => HandleProgress(e, _folders);
- remotefiles = new BackgroundWorker();
- remotefiles.WorkerReportsProgress = true;
- remotefiles.WorkerSupportsCancellation = false;
- //remotefiles.DoWork += RemoteFilesRefresh;
- remotefiles.ProgressChanged += (o, e) => HandleProgress(e, _files);
- localfiles = new BackgroundWorker();
- localfiles.WorkerReportsProgress = true;
- localfiles.WorkerSupportsCancellation = false;
- localfiles.DoWork += LocalFilesRefresh;
- localfiles.ProgressChanged += (o, e) => HandleProgress(e, _files);
- _waitcursortimer = new DispatcherTimer();
- _waitcursortimer.Interval = TimeSpan.FromMilliseconds(50F);
- _waitcursortimer.Tick += CheckWaitCursor;
- _waitcursortimer.IsEnabled = true;
- }
- public Guid ParentID { get; set; }
-
- public JobPanelSettings Settings { get; set; }
-
- public bool IsReady { get; set; }
- public event DataModelUpdateEvent OnUpdateDataModel;
- public void CreateToolbarButtons(IPanelHost host)
- {
- }
- public string SectionName => "Job Documents";
- public DataModel DataModel(Selection selection)
- {
- return new JobDetailsDataModel(new Filter<Job>(x => x.ID).IsEqualTo(ParentID));
- }
- public void Heartbeat(TimeSpan time)
- {
- }
- public void Refresh()
- {
- if (ParentID == Guid.Empty || ParentID == CoreUtils.FullGuid)
- return;
- // using (SvnClient svnClient = new SvnClient())
- // {
- // svnClient.Authentication.Clear();
- // svnClient.Authentication.DefaultCredentials = new System.Net.NetworkCredential("admin", "admin");
- // svnClient.Authentication.SslServerTrustHandlers += (o, e) =>
- // {
- // e.AcceptedFailures = e.Failures;
- // e.Save = true;
- // };
- //
- // //var statusArgs = new SvnStatusArgs();
- // //statusArgs.Depth = SvnDepth.Infinity;
- // //statusArgs.RetrieveAllEntries = true;
- // //Collection<SvnStatusEventArgs> statuses;
- // //bool bResult = svnClient.GetStatus(Path.Combine(_localroot, GetFolderPath("\\")), statusArgs, out statuses);
- // //foreach (SvnStatusEventArgs statusEventArgs in statuses)
- // //{
- // // if (statusEventArgs.LocalContentStatus == SvnStatus.Modified)
- // // System.Console.WriteLine("Modified file: " + statusEventArgs.Path);
- // //}
- // }
- _folders.Clear();
- ;
- _files.Clear();
- CheckAndRunWorkers(remotefolders, localfolders, GetFolderPath("/"), GetFolderPath("\\"));
- }
- public Dictionary<string, object[]> Selected()
- {
- return new Dictionary<string, object[]>();
- }
- public void Setup()
- {
- settings = new UserConfiguration<JobDocumentsScreenSettings>().Load();
- SplitPanel.View = settings.ViewType == ScreenViewType.Register ? DynamicSplitPanelView.Master :
- settings.ViewType == ScreenViewType.Details ? DynamicSplitPanelView.Detail : DynamicSplitPanelView.Combined;
- SplitPanel.AnchorWidth = settings.AnchorWidth;
- Folders.ParentPropertyName = "ID";
- Folders.ChildPropertyName = "ParentID";
- Folders.SelfRelationRootValue = Guid.Empty;
- Folders.AutoExpandMode = AutoExpandMode.RootNodesExpanded;
- Folders.ItemsSource = _folders;
- Files.ItemsSource = _files;
- }
- public void Shutdown()
- {
- }
- private void SplitPanel_OnChanged(object sender, DynamicSplitPanelSettings e)
- {
- settings.ViewType = SplitPanel.View == DynamicSplitPanelView.Master ? ScreenViewType.Register :
- SplitPanel.View == DynamicSplitPanelView.Detail ? ScreenViewType.Details : ScreenViewType.Combined;
- settings.AnchorWidth = SplitPanel.AnchorWidth;
- new UserConfiguration<JobDocumentsScreenSettings>().Save(settings);
- }
- private void Folders_AutoGeneratingColumn(object sender, TreeGridAutoGeneratingColumnEventArgs e)
- {
- if (e.Column.MappingName == "DisplayName")
- e.Column.ColumnSizer = TreeColumnSizer.Star;
- else if (e.Column.MappingName.Equals("RemoteSize") || e.Column.MappingName.Equals("RemoteTime") ||
- e.Column.MappingName.Equals("LocalSize") ||
- e.Column.MappingName.Equals("LocalTime"))
- //e.Column.ColumnSizer = TreeColumnSizer.Auto;
- e.Cancel = true;
- else
- e.Cancel = true;
- }
- private void Folders_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- }
- private void Folders_SelectionChanged(object sender, GridSelectionChangedEventArgs e)
- {
- _files.Clear();
- var folder = (e.AddedItems.FirstOrDefault() as TreeGridRowInfo)?.RowData as SVNFolder;
- if (folder != null)
- CheckAndRunWorkers(remotefiles, localfiles, folder, folder);
- }
- private void Files_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
- {
- e.Column.HeaderStyle = Resources["FileHeaderStyle"] as Style;
- if (e.Column.MappingName == "Status")
- {
- e.Column = new GridTemplateColumn { CellTemplate = Resources["ImageTemplate"] as DataTemplate };
- e.Column.Width = 30;
- }
- else if (e.Column.MappingName == "DisplayName")
- {
- e.Column.ColumnSizer = GridLengthUnitType.Star;
- e.Column.HeaderText = "File Name";
- }
- else if (e.Column.MappingName.Equals("RemoteSize") || e.Column.MappingName.Equals("RemoteTime") ||
- e.Column.MappingName.Equals("LocalSize") ||
- e.Column.MappingName.Equals("LocalTime"))
- // e.Column.ColumnSizer = GridLengthUnitType.Auto;
- {
- e.Cancel = true;
- }
- else
- {
- e.Cancel = true;
- }
- }
- #region Background Worker Support Functions
- private void CheckWaitCursor(object sender, EventArgs args)
- {
- if (!remotefolders.IsBusy && !remotefiles.IsBusy && !localfolders.IsBusy && !localfiles.IsBusy)
- {
- _waitcursortimer.IsEnabled = false;
- if (_waitcursor != null)
- {
- _waitcursor.Dispose();
- _waitcursor = null;
- }
- }
- }
- private void CheckAndRunWorkers(BackgroundWorker remote, BackgroundWorker local, object remoteparameter, object localparameter)
- {
- if (remote.IsBusy)
- {
- MessageBox.Show(string.Format("{0} is Busy!", remote.GetType()));
- return;
- }
- if (localfiles.IsBusy)
- {
- MessageBox.Show(string.Format("{0} is Busy!", local.GetType()));
- return;
- }
- _waitcursor = new WaitCursor();
- remote.RunWorkerAsync(remoteparameter);
- local.RunWorkerAsync(localparameter);
- _waitcursortimer.IsEnabled = true;
- }
- private string GetFolderPath(string separator)
- {
- if (lastjobid != ParentID)
- {
- jobnumber = new Client<Job>().Query(
- new Filter<Job>(x => x.ID).IsEqualTo(ParentID),
- new Columns<Job>(x => x.JobNumber)
- ).Rows.Select(r => r.Get<Job, string>(c => c.JobNumber)).FirstOrDefault();
- lastjobid = ParentID;
- }
- return string.Join(separator, "Jobs", jobnumber);
- }
- private static Uri GetRelativeUri(string segment)
- {
- var sSeg = string.Format("./{0}/", segment.TrimStart('/').TrimEnd('/'));
- var uSeg = new Uri(sSeg, UriKind.Relative);
- return uSeg;
- }
- private void HandleProgress<T>(ProgressChangedEventArgs e, ObservableCollection<T> collection, Action<T, Uri> action = null)
- where T : SVNObject
- {
- if (e.UserState is Exception)
- {
- var err = e.UserState as Exception;
- var messages = new List<string>();
- messages.Add("===============================================");
- messages.Add(string.Format("{0} Exception Caught!", err.GetType()));
- while (err != null)
- {
- messages.Add("===============================================");
- messages.Add(err.Message);
- messages.Add(err.StackTrace);
- err = err.InnerException;
- }
- messages.Add("===============================================");
- MessageBox.Show(string.Join("\n", messages));
- }
- else if (e.UserState is SyncEntry)
- {
- UpdateCollection(e.UserState as SyncEntry, collection, action);
- }
- }
- private void UpdateCollection<T>(SyncEntry entry, ObservableCollection<T> items, Action<T, Uri> action) where T : SVNObject
- {
- if (entry == null)
- return;
- var segments = entry.Path.Segments.Skip(entry.Parent.Segments.Length)
- .Select(x => x.TrimStart('/').TrimEnd('/').TrimStart('\\').TrimEnd('\\'))
- .ToArray();
- if (!segments.Any())
- return;
- var path = segments.Reverse().Skip(1).Reverse().ToArray();
- var name = segments.LastOrDefault();
- var existing = items.FirstOrDefault(x => x.Equals(segments));
- if (existing == null)
- {
- var parent = items.FirstOrDefault(x => x.Equals(path));
- existing = Activator.CreateInstance(typeof(T), path, name, parent) as T;
- items.Add(existing);
- }
- if (entry is LocalSyncEntry)
- {
- existing.LocalSize = entry.Size;
- existing.LocalTime = entry.Modified;
- }
- else if (entry is RemoteSyncEntry)
- {
- existing.RemoteSize = entry.Size;
- existing.RemoteTime = entry.Modified;
- }
- }
- #endregion
- #region Local File Processing
- private void LocalFilesRefresh(object sender, DoWorkEventArgs args)
- {
- var folder = args.Argument as SVNFolder;
- if (folder == null)
- return;
- var root = Path.Combine(_localroot, GetFolderPath("\\"));
- foreach (var segment in folder.Path)
- root = Path.Combine(root, segment);
- root = Path.Combine(root, folder.Name);
- root = Uri.UnescapeDataString(root);
- if (!Directory.Exists(root))
- return;
- try
- {
- var files = Directory.EnumerateFiles(root);
- foreach (var file in files)
- {
- var info = new FileInfo(file);
- localfiles.ReportProgress(0,
- new LocalSyncEntry { Parent = new Uri(root), Path = new Uri(file), Modified = info.LastWriteTime, Size = info.Length });
- }
- }
- catch (Exception e)
- {
- localfiles.ReportProgress(100, e);
- }
- }
- private void LocalFoldersRefresh(object sender, DoWorkEventArgs args)
- {
- var folderroot = args.Argument as string;
- if (string.IsNullOrWhiteSpace(folderroot))
- return;
- try
- {
- var root = Path.Combine(_localroot, folderroot.TrimStart('\\'));
- root = Uri.UnescapeDataString(root);
- var folders = new List<string> { root };
- while (folders.Any())
- {
- var folder = folders.First();
- folders.Remove(folder);
- if (Directory.Exists(folder))
- {
- var items = Directory.EnumerateDirectories(folder);
- foreach (var item in items)
- {
- var info = new FileInfo(item);
- if (!string.IsNullOrEmpty(item) && !string.Equals(item, folder) && !string.Equals(item, root) &&
- !info.Attributes.HasFlag(FileAttributes.Hidden))
- {
- folders.Add(item);
- localfolders.ReportProgress(0,
- new LocalSyncEntry { Parent = new Uri(root), Path = new Uri(item), Modified = info.LastWriteTime, Size = 0L });
- }
- }
- }
- }
- }
- catch (Exception e)
- {
- localfolders.ReportProgress(100, e);
- }
- }
- #endregion
- #region Remote File Processing
- // private static bool ListRemoteDirectory(SvnClient svnClient, Uri uri, out Collection<SvnListEventArgs> items, bool create)
- // {
- // try
- // {
- // return svnClient.GetList(uri, out items);
- // }
- // catch
- // {
- // if (create)
- // {
- // svnClient.RemoteCreateDirectory(uri, new SvnCreateDirectoryArgs() { LogMessage = "Auto Created Folder" });
- // return svnClient.GetList(uri, out items);
- // }
- // else
- // {
- // items = new Collection<SvnListEventArgs>();
- // return false;
- // }
- // }
- // }
- // private void RemoteFilesRefresh(object sender, DoWorkEventArgs args)
- // {
- //
- // var folder = args.Argument as SVNFolder;
- // if (folder == null)
- // return;
- //
- // Uri uri = new Uri(_serverroot, GetRelativeUri(GetFolderPath("/")));
- // foreach (var segment in folder.Path)
- // {
- // Uri uSeg = GetRelativeUri(segment);
- // uri = new Uri(uri, uSeg);
- // }
- // uri = new Uri(uri, GetRelativeUri(folder.Name));
- //
- // try
- // {
- // using (SvnClient svnClient = new SvnClient())
- // {
- // svnClient.Authentication.Clear();
- // svnClient.Authentication.DefaultCredentials = new System.Net.NetworkCredential("admin", "admin");
- // svnClient.Authentication.SslServerTrustHandlers += (o, e) =>
- // {
- // e.AcceptedFailures = e.Failures;
- // e.Save = true;
- // };
- //
- // Collection<SvnListEventArgs> items;
- // if (ListRemoteDirectory(svnClient, uri, out items, false))
- // {
- // foreach (SvnListEventArgs item in items)
- // {
- // bool bInfo = svnClient.GetInfo(item.Uri, out SvnInfoEventArgs info);
- //
- // if ((!String.IsNullOrEmpty(item.Name)) && (item.Entry.NodeKind == SvnNodeKind.File))
- // {
- // //bool bStatus = svnClient.GetStatus(item.Uri.AbsoluteUri, out Collection<SvnStatusEventArgs> statuses);
- // remotefiles.ReportProgress(0, new RemoteSyncEntry() { Parent = uri, Path = item.Uri, Modified = item.Entry.Time, Size = info.RepositorySize });
- // }
- // }
- // }
- // }
- // }
- // catch (Exception e)
- // {
- // remotefiles.ReportProgress(100, e);
- // }
- // }
- //
- // private void RemoteFoldersRefresh(object sender, DoWorkEventArgs args)
- // {
- //
- // String folderroot = args.Argument as String;
- // if (String.IsNullOrWhiteSpace(folderroot))
- // return;
- //
- // try
- // {
- // using (SvnClient svnClient = new SvnClient())
- // {
- // svnClient.Authentication.Clear();
- // svnClient.Authentication.DefaultCredentials = new System.Net.NetworkCredential("admin", "admin");
- // svnClient.Authentication.SslServerTrustHandlers += (o,e) =>
- // {
- // e.AcceptedFailures = e.Failures;
- // e.Save = true;
- // };
- //
- // Uri root = new Uri(_serverroot, GetRelativeUri(folderroot));
- // List<Uri> uris = new List<Uri>() { root };
- // while (uris.Any())
- // {
- // var uri = uris.First();
- // uris.Remove(uri);
- // Collection<SvnListEventArgs> items;
- // if (ListRemoteDirectory(svnClient, uri, out items, true))
- // {
- // foreach (SvnListEventArgs item in items)
- // {
- // if ((!String.IsNullOrEmpty(item.Name)) && (!Uri.Equals(root, item.Uri)) && (!Uri.Equals(uri, item.Uri)) && (item.Entry.NodeKind == SvnNodeKind.Directory))
- // {
- // uris.Add(item.Uri);
- // remotefolders.ReportProgress(0, new RemoteSyncEntry() { Parent = root, Path = item.Uri, Modified = item.Entry.Time, Size = item.Entry.FileSize });
- // }
- // }
- // }
- // }
- // }
- // }
- // catch (Exception e)
- // {
- // remotefolders.ReportProgress(100, e);
- // }
- // }
- #endregion
- }
- }
|