diff Chronosv2/source/DragAndDrop/DropHelper.cs @ 10:443821e55f06

Initial cleaned up add from Codeplex files
author stevenh7776 stevenhollidge@hotmail.com
date Tue, 21 Feb 2012 17:25:44 +0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Chronosv2/source/DragAndDrop/DropHelper.cs	Tue Feb 21 17:25:44 2012 +0700
@@ -0,0 +1,333 @@
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using Chronos.Presentation.Core.VirtualDesktops;
+using Chronos.Presentation.Core.Widgets;
+using Chronos.Presentation.ViewModel;
+using Chronos.Presentation.Windows.Controls;
+using nRoute.Services;
+using nRoute.SiteMaps;
+
+namespace Chronos.Presentation.DragAndDrop
+{
+    public sealed class DropHelper
+    {
+        #region · Consts ·
+
+        const string UrlDataFormat = "text/x-moz-url";
+
+        #endregion
+
+        #region · Fields ·
+
+        private UIElement       dropTarget = null;
+        private string[]        datatypes  = { typeof(UIElement).ToString(), "Text" };        
+        private DragDropEffects allowedEffects;
+
+        #endregion
+
+        #region · Properties ·
+
+        public string[] AllowedDataTypes
+        {
+            get { return this.datatypes; }
+            set
+            {
+                this.datatypes = value;
+
+                for (int x = 0; x < this.datatypes.Length; x++)
+                {
+                    this.datatypes[x] = this.datatypes[x].ToLower();
+                }
+            }
+        }
+
+        public DragDropEffects AllowedEffects
+        {
+            get { return this.allowedEffects; }
+            set { this.allowedEffects = value; }
+        }
+
+        #endregion
+
+        #region · Constructors ·
+
+        public DropHelper(UIElement wrapper)
+        {
+            this.dropTarget = wrapper;
+
+            this.dropTarget.AllowDrop  = true;
+            this.dropTarget.DragOver   += new DragEventHandler(DropTarget_DragOver);
+            this.dropTarget.Drop       += new DragEventHandler(DropTarget_Drop);
+        }
+
+        #endregion
+
+        #region · DropTarget Event Handlers ·
+
+        private void DropTarget_Drop(object sender, DragEventArgs e)
+        {
+            IDataObject     data            = e.Data;
+            DragDataWrapper dw              = null;
+            bool            isDataOperation = false;
+           
+            Debug.Assert(data != null);
+
+            if (data.GetDataPresent(typeof(DragDataWrapper).ToString()))
+            {
+                dw = data.GetData(typeof(DragDataWrapper).ToString()) as DragDataWrapper;
+
+                Debug.Assert(dw.Shim != null);
+
+                if ((dw.Shim.SupportedActions & DragDropProviderActions.Data) != 0)
+                {
+                    isDataOperation = true;
+                }
+            }
+
+            // Try a BRUTE FORCE APPROACH on UIElement just to show how it could be done
+            // BUT NOT ENDORSING IT!!! 
+            if (!isDataOperation)
+            {
+                if (this.dropTarget is Canvas)
+                {
+                    if (e.Data.GetDataPresent(DataFormats.FileDrop))
+                    {
+                        this.DropFileLink(e);
+                    }
+                    else if (e.Data.GetDataPresent(UrlDataFormat))
+                    {
+                        this.DropUrl(e);
+                    }
+                }
+            }
+            else
+            {
+                Debug.Assert(dw != null);
+                Debug.Assert(dw.Shim != null);
+
+                object rawdata = dw.Data;
+
+                if (this.dropTarget is ItemsControl)
+                {
+                    this.DropItemsControlHandler(e, rawdata);
+                }
+                else if (dropTarget is Canvas)
+                {
+                    if (rawdata is IWidget)
+                    {
+                        this.DropCanvasWidget(e, rawdata as IWidget);
+                    }
+                    else if (rawdata is SiteMapNode)
+                    {
+                        this.DropCanvasInternalLink(e, rawdata as NavigationNode);
+                    }
+                }
+            }
+
+            e.Handled = true;
+        }
+      
+        private void DropTarget_DragOver(object sender, DragEventArgs e)
+        {
+            string[]    types = e.Data.GetFormats();
+            bool        match = false;
+
+            if (datatypes == null || types == null)
+            {
+                //TODO: ??? Should we set for DragDropEffects.None? 
+                return;
+            }
+
+            foreach (string s in types)
+            {
+                foreach (string type in datatypes)
+                {
+                    match = (s.ToLower() == type);
+
+                    if (match)
+                    {
+                        break;
+                    }
+                }
+            
+                if (match)
+                {
+                    break;
+                }
+            }
+
+            if (match)
+            {
+                e.Effects = AllowedEffects;
+                e.Handled = true;
+            }
+        }
+
+        #endregion
+
+        #region · Drop Handlers Methods ·
+
+        private void DropCanvasWidget(DragEventArgs e, IWidget dropObject)
+        {
+            ServiceLocator.GetService<IVirtualDesktopManager>()
+                          .Show
+            (
+                dropObject.CreateView() as WidgetElement, 
+                e.GetPosition(this.dropTarget)
+            );
+        }
+
+        private void DropItemsControlHandler(DragEventArgs e, object rawdata)
+        {
+            ItemsControl    ic      = this.dropTarget as ItemsControl;
+            IList           list    = ic.ItemsSource as IList;
+
+            if (list == null)
+            {
+                list = ic.Items as System.Collections.IList;
+            }
+
+            if (list != null)
+            {
+                if (!list.Contains(rawdata))
+                {
+                    // Here we do not check for Move | Copy ... because this is a DATA operation .. No parent relationshop at all ... 
+                    list.Add(rawdata);
+                }
+                else
+                {
+                    // nothing was done ... 
+                    e.Effects = DragDropEffects.None;
+                }
+            }
+            else
+            {
+                e.Effects = DragDropEffects.None;
+            }
+        }
+
+        private void DropFileLink(DragEventArgs e)
+        {
+            // External link drop
+            Point       position    = e.GetPosition(this.dropTarget);
+            string[]    filenames   = e.Data.GetData(DataFormats.FileDrop, true) as string[];
+
+            e.Effects = DragDropEffects.Link;
+
+            foreach (string filename in filenames)
+            {
+                ServiceLocator.GetService<IVirtualDesktopManager>()
+                              .CreateShortcut<ExternalShortcutViewModel>
+                (
+                    Path.GetFileNameWithoutExtension(filename), filename, position
+                );
+            }
+        }
+
+        private void DropUrl(DragEventArgs e)
+        {
+            // External link drop
+            Point   position    = e.GetPosition(this.dropTarget);
+            String  data        = null;
+
+            using (MemoryStream stream = e.Data.GetData(UrlDataFormat, true) as MemoryStream)
+            {
+                using (StreamReader reader = new StreamReader(stream, Encoding.Unicode))
+                {
+                    data = reader.ReadToEnd().Replace("\0", "");
+                }
+            }
+
+            if (!String.IsNullOrEmpty(data))
+            {
+                string[] elements = data.Split('\n');
+
+                e.Effects = DragDropEffects.Link;
+
+                if (!String.IsNullOrWhiteSpace(elements[0]) &&
+                    !String.IsNullOrWhiteSpace(elements[1]))
+                {
+                    ServiceLocator.GetService<IVirtualDesktopManager>()
+                                  .CreateShortcut<ExternalShortcutViewModel>
+                    (
+                        elements[1], 
+                        elements[0], 
+                        position
+                    );
+                }
+            }
+        }
+
+        private void DropCanvasInternalLink(DragEventArgs e, NavigationNode siteMapNode)
+        {
+            Point position = e.GetPosition(this.dropTarget);
+
+            ServiceLocator.GetService<IVirtualDesktopManager>()
+                          .CreateShortcut<InternalShortcutViewModel>
+            (
+                siteMapNode.Title, 
+                siteMapNode.Url, 
+                position
+            );
+        }
+        
+        #endregion
+
+        #region · Private Methods ·
+
+        private bool Unparent(DragDataWrapper dw, UIElement uie)
+        {
+            bool success = false;
+
+            if (dw != null)
+            {
+                if (dw.AllowChildrenRemove)
+                {
+                    dw.Shim.UnParent();
+                }
+            }
+
+            if (!success) // BRUTE FORCE 
+            {
+                if (uie is FrameworkElement)
+                {
+                    FrameworkElement fe = uie as FrameworkElement;
+
+                    if (fe.Parent != null)
+                    {
+                        if (fe.Parent is Panel)
+                        {
+                            try
+                            {
+                                ((Panel)(fe.Parent)).Children.Remove(uie);
+                                success = true;
+                            }
+                            catch (Exception)
+                            {
+#if DEBUG
+                                System.Diagnostics.Debug.Assert(false);
+#endif
+                            }
+                        }
+                    }
+                    else if (fe.Parent is ContentControl)
+                    {
+                        ContentControl cc = fe.Parent as ContentControl;
+
+                        cc.Content  = null;
+                        success     = true;
+                    }
+                }
+            }
+
+            return success;
+        }
+
+        #endregion
+    }
+}