Beispiel #1
0
        private void DoPastePointer(Node targetNode)
        {
            try
            {
                //todo: lots of copy/paste that could be cleaned up and deduped with DoPaste
                var node                  = GetClipData();
                var sourceObj             = node?.Obj as AssetsObject;
                var targetObj             = targetNode?.Obj;
                var targetOwnerNode       = FindFirstParent(targetNode);
                var targetOwnerObj        = targetOwnerNode?.Obj as AssetsObject;
                var targetDirectParentObj = targetNode?.Parent?.Obj;

                if (node == null || node.Obj == null || node.StubToNode != null || sourceObj == null || targetObj == null)
                {
                    return;
                }
                if (targetOwnerObj == null)
                {
                    Log.LogErr($"Tried to paste, but couldn't find the assetsobject owner on node '{targetNode.Text}'");
                    return;
                }
                if (targetDirectParentObj == null)
                {
                    Log.LogErr($"Tried to paste, but couldn't find the actual parent on node '{targetNode.Text}'");
                    return;
                }
                if (string.IsNullOrWhiteSpace(targetNode.ParentPropertyName))
                {
                    Log.LogErr($"Tried to paste, but parent property name was null on node '{targetNode.Text}'");
                    return;
                }
                if (sourceObj.ObjectInfo.ParentFile.Manager != targetOwnerObj.ObjectInfo.ParentFile.Manager)
                {
                    //can't paste a pointer to a different assets manager instance
                    return;
                }



                bool updated = false;
                var  ptrList = targetObj as IEnumerable <ISmartPtr <AssetsObject> >;
                if (ptrList != null)
                {
                    try
                    {
                        var pointer = ReflectionHelper.MakeTypedPointer(targetOwnerObj, sourceObj);
                        ReflectionHelper.AddObjectToEnum(pointer, ptrList);
                        updated = true;
                    }
                    catch (Exception ex)
                    {
                        Log.LogErr($"Adding object to collection failed!", ex);
                        return;
                    }
                }

                var ptr = targetObj as ISmartPtr <AssetsObject>;
                if (ptr != null)
                {
                    try
                    {
                        var pointer    = ReflectionHelper.MakeTypedPointer(targetOwnerObj, sourceObj);
                        var oldPointer = ReflectionHelper.GetPtrFromPropName(targetDirectParentObj, targetNode.ParentPropertyName);
                        ReflectionHelper.AssignPtrToPropName(targetDirectParentObj, targetNode.ParentPropertyName, pointer);
                        oldPointer.Dispose();
                        updated = true;
                    }
                    catch (Exception ex)
                    {
                        Log.LogErr($"Replacing pointer failed on {targetDirectParentObj?.GetType()?.Name}.{targetNode.ParentPropertyName}!");
                    }
                }
                if (updated)
                {
                    var res = (tvExplorer.Nodes[0].Tag as Node).GetNodePath(targetNode);
                    //update node, hopefully we won't have to repopulate the entire thing?
                    Node newnode = Node.MakeNode(targetOwnerObj);
                    var  targetOwnerParentNode = targetOwnerNode.Parent;
                    var  idx = targetOwnerNode.Parent.Nodes.IndexOf(targetOwnerNode);
                    targetOwnerParentNode.Nodes.RemoveAt(idx);
                    targetOwnerParentNode.Nodes.Insert(idx, newnode);
                    newnode.Parent             = targetOwnerParentNode;
                    newnode.ParentPropertyName = targetOwnerNode.ParentPropertyName;

                    //TODO: find a better way to refresh only the altered tree node and not the whole thing


                    var ds = DataSource;
                    DataSource = null;
                    DataSource = ds;

                    TreeNode tn = tvExplorer.Nodes[0];
                    while (res.Count > 0)
                    {
                        tn = tn.Nodes[res.Pop()] as TreeNode;
                    }
                    tn.EnsureVisible();
                    SelectedNode = tn;
                    tn.Expand();

                    return;
                }
            }
            catch (Exception ex)
            {
                Log.LogErr($"Exception trying to paste object!", ex);
                MessageBox.Show("Failed to paste object!");
            }
        }
Beispiel #2
0
        // yeesh, so much copy/paste code.  I WILL DO BETTER THAN THIS

        //todo: refactor
        private void DoPaste(Node targetNode)
        {
            try
            {
                var node      = GetClipData();
                var sourceObj = node?.Obj as AssetsObject;
                var targetObj = targetNode?.Obj;

                AssetsFile   targetFile            = null;
                Node         targetOwnerNode       = null;
                AssetsObject targetOwnerObj        = null;
                object       targetDirectParentObj = null;

                if (node == null || node.Obj == null || node.StubToNode != null || sourceObj == null || targetObj == null)
                {
                    return;
                }
                bool isFile = false;
                if (targetObj is AssetsFile)
                {
                    isFile          = true;
                    targetFile      = targetObj as AssetsFile;
                    targetOwnerNode = targetNode.Parent;
                }
                else
                {
                    targetOwnerNode       = FindFirstParent(targetNode);
                    targetOwnerObj        = targetOwnerNode?.Obj as AssetsObject;
                    targetDirectParentObj = targetNode?.Parent?.Obj;
                    if (targetOwnerObj == null)
                    {
                        Log.LogErr($"Tried to paste, but couldn't find the assetsobject owner on node '{targetNode.Text}'");
                        return;
                    }
                    if (targetDirectParentObj == null)
                    {
                        Log.LogErr($"Tried to paste, but couldn't find the actual parent on node '{targetNode.Text}'");
                        return;
                    }
                    if (string.IsNullOrWhiteSpace(targetNode.ParentPropertyName))
                    {
                        Log.LogErr($"Tried to paste, but parent property name was null on node '{targetNode.Text}'");
                        return;
                    }
                    targetFile = targetOwnerObj.ObjectInfo.ParentFile;
                }
                List <AssetsObject> addedObjects = new List <AssetsObject>();
                AssetsObject        cloned       = null;
                try
                {
                    var exclus = GetExclusionsForObject(sourceObj, targetFile);
                    cloned = sourceObj.ObjectInfo.DeepClone(targetFile, addedObjects: addedObjects, exclusions: exclus);
                }
                catch (Exception ex)
                {
                    Log.LogErr($"Exception trying to clone object of type {sourceObj.GetType().Name}!", ex);
                    try
                    {
                        foreach (var ao in addedObjects)
                        {
                            targetFile.DeleteObject(ao);
                        }
                    }
                    catch (Exception ex2)
                    {
                        Log.LogErr("Failed to clean up after bad clone!", ex2);
                        MessageBox.Show("A clone failed and the rollback failed too.  The assets files are in an unknown state!");
                    }
                    return;
                }
                bool updated = false;
                if (isFile)
                {
                    updated = true;
                }
                else
                {
                    var ptrList = targetObj as IEnumerable <ISmartPtr <AssetsObject> >;
                    if (ptrList != null)
                    {
                        try
                        {
                            var pointer = ReflectionHelper.MakeTypedPointer(targetOwnerObj, cloned);
                            ReflectionHelper.AddObjectToEnum(pointer, ptrList);
                            updated = true;
                        }
                        catch (Exception ex)
                        {
                            Log.LogErr($"Adding object to collection failed!", ex);
                            MessageBox.Show("Object was created, but could not be attached to the collection!");
                            return;
                        }
                    }

                    var ptr = targetObj as ISmartPtr <AssetsObject>;
                    if (ptr != null)
                    {
                        try
                        {
                            var pointer    = ReflectionHelper.MakeTypedPointer(targetOwnerObj, cloned);
                            var oldPointer = ReflectionHelper.GetPtrFromPropName(targetDirectParentObj, targetNode.ParentPropertyName);
                            ReflectionHelper.AssignPtrToPropName(targetDirectParentObj, targetNode.ParentPropertyName, pointer);
                            oldPointer.Dispose();
                            updated = true;
                        }
                        catch (Exception ex)
                        {
                            Log.LogErr($"Replacing pointer failed on {targetDirectParentObj?.GetType()?.Name}.{targetNode.ParentPropertyName}!");
                        }
                    }
                }
                if (updated)
                {
                    var res = (tvExplorer.Nodes[0].Tag as Node).GetNodePath(targetNode);
                    //update node, hopefully we won't have to repopulate the entire thing?



                    if (!isFile)
                    {
                        Node newNode = Node.MakeNode(targetOwnerObj);
                        var  targetOwnerParentNode = targetOwnerNode.Parent;
                        var  idx = targetOwnerNode.Parent.Nodes.IndexOf(targetOwnerNode);
                        targetOwnerParentNode.Nodes.RemoveAt(idx);
                        targetOwnerParentNode.Nodes.Insert(idx, newNode);
                        newNode.Parent             = targetOwnerParentNode;
                        newNode.ParentPropertyName = targetOwnerNode.ParentPropertyName;
                    }
                    else
                    {
                        Node newNode = Node.MakeNode((AssetsFile)targetObj);
                        var  idx     = targetNode.Parent.Nodes.IndexOf(targetNode);
                        targetNode.Parent.Nodes.RemoveAt(idx);
                        targetNode.Parent.Nodes.Insert(idx, newNode);
                        newNode.Parent             = targetNode;
                        newNode.ParentPropertyName = null;
                    }

                    //TODO: find a better way to refresh only the altered tree node and not the whole thing

                    var ds = DataSource;
                    DataSource = null;
                    DataSource = ds;

                    TreeNode tn = tvExplorer.Nodes[0];
                    while (res.Count > 0)
                    {
                        tn = tn.Nodes[res.Pop()] as TreeNode;
                    }
                    tn.EnsureVisible();
                    SelectedNode = tn;
                    tn.Expand();

                    return;
                }
            }
            catch (Exception ex)
            {
                Log.LogErr($"Exception trying to paste object!", ex);
                MessageBox.Show("Failed to paste object!");
            }
        }