diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.FileSystem/FileExplorerControl.cs')
| -rw-r--r-- | Software/Visual_Studio/Tango.FileSystem/FileExplorerControl.cs | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileExplorerControl.cs b/Software/Visual_Studio/Tango.FileSystem/FileExplorerControl.cs new file mode 100644 index 000000000..23cac7733 --- /dev/null +++ b/Software/Visual_Studio/Tango.FileSystem/FileExplorerControl.cs @@ -0,0 +1,423 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.Core.IO; + +namespace Tango.FileSystem +{ + public class FileExplorerControl : Control + { + private ListBox _listBox; + private DataGrid _datagrid; + private bool _preventSynchronization; + private Point _dragOutStartPoint; + private bool _isMouseDown; + private List<FileSystemItem> _selectedItemsBeforeDrag; + + public IFileSystemContainer CurrentItem + { + get { return (IFileSystemContainer)GetValue(CurrentItemProperty); } + set { SetValue(CurrentItemProperty, value); } + } + public static readonly DependencyProperty CurrentItemProperty = + DependencyProperty.Register("CurrentItem", typeof(IFileSystemContainer), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public FileSystemItem SelectedItem + { + get { return (FileSystemItem)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(FileSystemItem), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ICommand ItemDoubleClickedCommand + { + get { return (ICommand)GetValue(ItemDoubleClickedCommandProperty); } + set { SetValue(ItemDoubleClickedCommandProperty, value); } + } + public static readonly DependencyProperty ItemDoubleClickedCommandProperty = + DependencyProperty.Register("ItemDoubleClickedCommand", typeof(ICommand), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ICommand DeleteCommand + { + get { return (ICommand)GetValue(DeleteCommandProperty); } + set { SetValue(DeleteCommandProperty, value); } + } + public static readonly DependencyProperty DeleteCommandProperty = + DependencyProperty.Register("DeleteCommand", typeof(ICommand), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ICommand DropCommand + { + get { return (ICommand)GetValue(DropCommandProperty); } + set { SetValue(DropCommandProperty, value); } + } + public static readonly DependencyProperty DropCommandProperty = + DependencyProperty.Register("DropCommand", typeof(ICommand), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ICommand DragCommand + { + get { return (ICommand)GetValue(DragCommandProperty); } + set { SetValue(DragCommandProperty, value); } + } + public static readonly DependencyProperty DragCommandProperty = + DependencyProperty.Register("DragCommand", typeof(ICommand), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ImageSource DriveIcon + { + get { return (ImageSource)GetValue(DriveIconProperty); } + set { SetValue(DriveIconProperty, value); } + } + public static readonly DependencyProperty DriveIconProperty = + DependencyProperty.Register("DriveIcon", typeof(ImageSource), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public ImageSource FolderIcon + { + get { return (ImageSource)GetValue(FolderIconProperty); } + set { SetValue(FolderIconProperty, value); } + } + public static readonly DependencyProperty FolderIconProperty = + DependencyProperty.Register("FolderIcon", typeof(ImageSource), typeof(FileExplorerControl), new PropertyMetadata(null)); + + public FileExplorerControlMode Mode + { + get { return (FileExplorerControlMode)GetValue(ModeProperty); } + set { SetValue(ModeProperty, value); } + } + public static readonly DependencyProperty ModeProperty = + DependencyProperty.Register("Mode", typeof(FileExplorerControlMode), typeof(FileExplorerControl), new PropertyMetadata(FileExplorerControlMode.Large)); + + public ObservableCollection<FileSystemItem> SelectedItems + { + get { return (ObservableCollection<FileSystemItem>)GetValue(SelectedItemsProperty); } + set { SetValue(SelectedItemsProperty, value); } + } + public static readonly DependencyProperty SelectedItemsProperty = + DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<FileSystemItem>), typeof(FileExplorerControl), new PropertyMetadata(null, (d, e) => (d as FileExplorerControl).OnSelectedItemsChanged())); + + public bool AllowDrag + { + get { return (bool)GetValue(AllowDragProperty); } + set { SetValue(AllowDragProperty, value); } + } + public static readonly DependencyProperty AllowDragProperty = + DependencyProperty.Register("AllowDrag", typeof(bool), typeof(FileExplorerControl), new PropertyMetadata(null)); + + static FileExplorerControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(FileExplorerControl), new FrameworkPropertyMetadata(typeof(FileExplorerControl))); + } + + public FileExplorerControl() + { + _selectedItemsBeforeDrag = new List<FileSystemItem>(); + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _listBox = GetTemplateChild("PART_listbox") as ListBox; + _datagrid = GetTemplateChild("PART_datagrid") as DataGrid; + + _listBox.SelectionChanged += _listBox_SelectionChanged; + _datagrid.SelectionChanged += _datagrid_SelectionChanged; + } + + protected override void OnPreviewKeyUp(KeyEventArgs e) + { + base.OnPreviewKeyUp(e); + + if (e.Key == Key.Delete) + { + if (SelectedItems != null && SelectedItems.Count > 0) + { + DeleteCommand?.Execute(SelectedItems); + } + } + } + + private void _datagrid_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (!_preventSynchronization) + { + _preventSynchronization = true; + + _listBox.SelectedItems.Clear(); + + foreach (var item in _datagrid.SelectedItems) + { + _listBox.SelectedItems.Add(item); + } + + SynchronizeSelectedItems(_listBox.SelectedItems); + + _preventSynchronization = false; + } + } + + private void _listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (!_preventSynchronization) + { + _preventSynchronization = true; + + _datagrid.SelectedItems.Clear(); + + foreach (var item in _listBox.SelectedItems) + { + _datagrid.SelectedItems.Add(item); + } + + SynchronizeSelectedItems(_listBox.SelectedItems); + + _preventSynchronization = false; + } + } + + private void SynchronizeSelectedItems(IList items) + { + if (SelectedItems == null) + { + SelectedItems = items.Cast<FileSystemItem>().ToObservableCollection(); + } + else + { + SelectedItems.Clear(); + + foreach (var item in items.Cast<FileSystemItem>().ToList()) + { + SelectedItems.Add(item); + } + } + } + + private void OnSelectedItemsChanged() + { + if (SelectedItems != null) + { + SelectedItems.CollectionChanged -= SelectedItems_CollectionChanged; + SelectedItems.CollectionChanged += SelectedItems_CollectionChanged; + SynchronizeControls(); + } + } + + private void SelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + SynchronizeControls(); + } + + private void SynchronizeControls() + { + if (_listBox == null) return; + + if (!_preventSynchronization) + { + _preventSynchronization = true; + + _listBox.SelectedItems.Clear(); + _datagrid.SelectedItems.Clear(); + + foreach (var item in SelectedItems) + { + _listBox.SelectedItems.Add(item); + _datagrid.SelectedItems.Add(item); + } + + _preventSynchronization = false; + } + } + + protected override void OnDrop(DragEventArgs e) + { + base.OnDrop(e); + + try + { + string[] items = (string[])e.Data.GetData(DataFormats.FileDrop, false); + + if (items != null && items.Length > 0) + { + List<FileSystemItem> fItems = new List<FileSystemItem>(); + + foreach (var item in items) + { + if (Directory.Exists(item)) + { + fItems.Add(new FolderItem() { Path = item }); + } + else if (File.Exists(item)) + { + fItems.Add(new FileItem() { Path = item }); + } + } + + if (fItems.Count > 0) + { + DropCommand?.Execute(fItems); + } + } + } + catch { } //Ignore + } + + protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonDown(e); + + if (!AllowDrag) return; + + if (e.OriginalSource is FrameworkElement) + { + var listBoxItem = (e.OriginalSource as FrameworkElement).FindAncestor<ListBoxItem>(); + var dataGridRow = (e.OriginalSource as FrameworkElement).FindAncestor<DataGridRow>(); + if (listBoxItem == null && dataGridRow == null) + { + return; + } + } + + _selectedItemsBeforeDrag.Clear(); + _selectedItemsBeforeDrag.AddRange(SelectedItems); + _isMouseDown = true; + AllowDrop = false; + _dragOutStartPoint = e.GetPosition(null); + } + + protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonUp(e); + AllowDrop = true; + _isMouseDown = false; + } + + protected async override void OnPreviewMouseMove(MouseEventArgs e) + { + base.OnPreviewMouseMove(e); + + if (_isMouseDown) + { + Point mpos = e.GetPosition(null); + Vector diff = this._dragOutStartPoint - mpos; + + if (e.LeftButton == MouseButtonState.Pressed && + Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) + { + if (SelectedItems.Count == 0) + { + return; + } + + + SelectedItems.Clear(); + + foreach (var item in _selectedItemsBeforeDrag) + { + SelectedItems.Add(item); + } + + List<Tuple<FileSystemItem, TemporaryFile>> dropItems = new List<Tuple<FileSystemItem, TemporaryFile>>(); + + foreach (var item in SelectedItems) + { + var tempFile = TemporaryManager.Default.CreateFile(".remote"); + dropItems.Add(new Tuple<FileSystemItem, TemporaryFile>(item, tempFile)); + } + + List<DragItem> notifyItems = new List<DragItem>(); + + List<FileSystemWatcher> watchers = new List<FileSystemWatcher>(); + + FileSystemEventHandler handler = (x, args) => + { + var detectedDropItem = dropItems.SingleOrDefault(y => y.Item2.FileName == System.IO.Path.GetFileName(args.FullPath)); + + Debug.WriteLine($"File Created: {args.FullPath}"); + + if (detectedDropItem != null) + { + try + { + detectedDropItem.Item2.Delete(); //Delete temp file. + + if (File.Exists(args.FullPath)) + { + File.Delete(args.FullPath); //Delete dropped fake file. + + dropItems.Remove(detectedDropItem); + + notifyItems.Add(new DragItem() + { + FileSystemItem = detectedDropItem.Item1, + Destination = System.IO.Path.GetDirectoryName(args.FullPath), + }); + + if (dropItems.Count == 0) + { + foreach (var watcher in watchers) + { + watcher.Dispose(); + } + + //Notify to user with all items! + Dispatcher.BeginInvoke(new Action(() => + { + DragCommand?.Execute(notifyItems); + })); + } + } + } + catch { } + } + else + { + Debug.WriteLine($"Not Found: {args.FullPath}"); + } + }; + + foreach (var drive in DriveInfo.GetDrives().Where(x => x.IsReady && (x.DriveType == DriveType.Fixed || x.DriveType == DriveType.Removable))) + { + FileSystemWatcher watcher = new FileSystemWatcher(drive.RootDirectory.FullName, "*.remote"); + watcher.IncludeSubdirectories = true; + watcher.EnableRaisingEvents = true; + watcher.Created += handler; + watchers.Add(watcher); + } + + string[] files = dropItems.Select(x => x.Item2.Path).ToArray(); + var ef = DragDrop.DoDragDrop(this, new DataObject(DataFormats.FileDrop, files, false), DragDropEffects.Copy); + + await Task.Delay(3000); + + foreach (var watcher in watchers) + { + watcher.Dispose(); + } + + if (dropItems.Count > 0) + { + //Notify about problem! + } + + _isMouseDown = false; + AllowDrop = true; + } + } + } + } +} |
