VsTeXProject.VisualStudio.Project.ProjectNode.AddItemWithSpecific C# (CSharp) Method

AddItemWithSpecific() private method

private AddItemWithSpecific ( uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string files, IntPtr dlgOwner, uint editorFlags, System.Guid &editorType, string physicalView, System.Guid &logicalView, VSADDRESULT result ) : int
itemIdLoc uint
op VSADDITEMOPERATION
itemName string
filesToOpen uint
files string
dlgOwner System.IntPtr
editorFlags uint
editorType System.Guid
physicalView string
logicalView System.Guid
result VSADDRESULT
return int
        public virtual int AddItemWithSpecific(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen,
            string[] files, IntPtr dlgOwner, uint editorFlags, ref Guid editorType, string physicalView,
            ref Guid logicalView, VSADDRESULT[] result)
        {
            if (files == null || result == null || files.Length == 0 || result.Length == 0)
            {
                return VSConstants.E_INVALIDARG;
            }

            // Locate the node to be the container node for the file(s) being added
            // only projectnode or foldernode and file nodes are valid container nodes
            // We need to locate the parent since the item wizard expects the parent to be passed.
            var n = NodeFromItemId(itemIdLoc);
            if (n == null)
            {
                return VSConstants.E_INVALIDARG;
            }

            while (!(n is ProjectNode) && !(n is FolderNode) && (!CanFileNodesHaveChilds || !(n is FileNode)))
            {
                n = n.Parent;
            }
            Debug.Assert(n != null,
                "We should at this point have either a ProjectNode or FolderNode or a FileNode as a container for the new filenodes");

            // handle link and runwizard operations at this point
            switch (op)
            {
                case VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE:
                    // we do not support this right now
                    throw new NotImplementedException("VSADDITEMOP_LINKTOFILE");

                case VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD:
                    result[0] = RunWizard(n, itemName, files[0], dlgOwner);
                    return VSConstants.S_OK;
            }

            var actualFiles = new string[files.Length];


            var flags = GetQueryAddFileFlags(files);

            var baseDir = GetBaseDirectoryForAddingFiles(n);
            // If we did not get a directory for node that is the parent of the item then fail.
            if (string.IsNullOrEmpty(baseDir))
            {
                return VSConstants.E_FAIL;
            }

            // Pre-calculates some paths that we can use when calling CanAddItems
            var filesToAdd = new List<string>();
            for (var index = 0; index < files.Length; index++)
            {
                var newFileName = string.Empty;

                var file = files[index];

                switch (op)
                {
                    case VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE:
                    {
                        var fileName = Path.GetFileName(itemName);
                        newFileName = Path.Combine(baseDir, fileName);
                    }
                        break;
                    case VSADDITEMOPERATION.VSADDITEMOP_OPENFILE:
                    {
                        var fileName = Path.GetFileName(file);
                        newFileName = Path.Combine(baseDir, fileName);
                    }
                        break;
                }
                filesToAdd.Add(newFileName);
            }

            // Ask tracker objects if we can add files
            if (!Tracker.CanAddItems(filesToAdd.ToArray(), flags))
            {
                // We were not allowed to add the files
                return VSConstants.E_FAIL;
            }

            if (!ProjectMgr.QueryEditProjectFile(false))
            {
                throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
            }

            // Add the files to the hierarchy
            var actualFilesAddedIndex = 0;
            for (var index = 0; index < filesToAdd.Count; index++)
            {
                HierarchyNode child;
                var overwrite = false;
                var newFileName = filesToAdd[index];

                var file = files[index];
                result[0] = VSADDRESULT.ADDRESULT_Failure;

                child = FindChild(newFileName);
                if (child != null)
                {
                    // If the file to be added is an existing file part of the hierarchy then continue.
                    if (NativeMethods.IsSamePath(file, newFileName))
                    {
                        result[0] = VSADDRESULT.ADDRESULT_Cancel;
                        continue;
                    }

                    var canOverWriteExistingItem = CanOverwriteExistingItem(file, newFileName);

                    if (canOverWriteExistingItem == (int) OleConstants.OLECMDERR_E_CANCELED)
                    {
                        result[0] = VSADDRESULT.ADDRESULT_Cancel;
                        return canOverWriteExistingItem;
                    }
                    if (canOverWriteExistingItem == VSConstants.S_OK)
                    {
                        overwrite = true;
                    }
                    else
                    {
                        return canOverWriteExistingItem;
                    }
                }

                // If the file to be added is not in the same path copy it.
                if (NativeMethods.IsSamePath(file, newFileName) == false)
                {
                    if (!overwrite && File.Exists(newFileName))
                    {
                        var message = string.Format(CultureInfo.CurrentCulture,
                            SR.GetString(SR.FileAlreadyExists, CultureInfo.CurrentUICulture), newFileName);
                        var title = string.Empty;
                        var icon = OLEMSGICON.OLEMSGICON_QUERY;
                        var buttons = OLEMSGBUTTON.OLEMSGBUTTON_YESNO;
                        var defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                        var messageboxResult = VsShellUtilities.ShowMessageBox(Site, title, message, icon, buttons,
                            defaultButton);
                        if (messageboxResult == NativeMethods.IDNO)
                        {
                            result[0] = VSADDRESULT.ADDRESULT_Cancel;
                            return (int) OleConstants.OLECMDERR_E_CANCELED;
                        }
                    }

                    // Copy the file to the correct location.
                    // We will suppress the file change events to be triggered to this item, since we are going to copy over the existing file and thus we will trigger a file change event. 
                    // We do not want the filechange event to ocur in this case, similar that we do not want a file change event to occur when saving a file.
                    var fileChange = site.GetService(typeof (SVsFileChangeEx)) as IVsFileChangeEx;
                    if (fileChange == null)
                    {
                        throw new InvalidOperationException();
                    }

                    try
                    {
                        ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(VSConstants.VSCOOKIE_NIL, newFileName, 1));
                        if (op == VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE)
                        {
                            AddFileFromTemplate(file, newFileName);
                        }
                        else
                        {
                            PackageUtilities.CopyUrlToLocal(new Uri(file), newFileName);
                        }
                    }
                    finally
                    {
                        ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(VSConstants.VSCOOKIE_NIL, newFileName, 0));
                    }
                }

                if (overwrite)
                {
                    OverwriteExistingItem(child);
                }
                else
                {
                    //Add new filenode/dependentfilenode
                    AddNewFileNodeToHierarchy(n, newFileName);
                }

                result[0] = VSADDRESULT.ADDRESULT_Success;
                actualFiles[actualFilesAddedIndex++] = newFileName;
            }

            // Notify listeners that items were appended.
            if (actualFilesAddedIndex > 0)
                n.OnItemsAppended(n);

            //Open files if this was requested through the editorFlags
            var openFiles = (editorFlags & (uint) __VSSPECIFICEDITORFLAGS.VSSPECIFICEDITOR_DoOpen) != 0;
            if (openFiles && actualFiles.Length <= filesToOpen)
            {
                for (var i = 0; i < filesToOpen; i++)
                {
                    if (!string.IsNullOrEmpty(actualFiles[i]))
                    {
                        var name = actualFiles[i];
                        var child = FindChild(name);
                        Debug.Assert(child != null, "We should have been able to find the new element in the hierarchy");
                        if (child != null)
                        {
                            IVsWindowFrame frame;
                            if (editorType == Guid.Empty)
                            {
                                var view = Guid.Empty;
                                ErrorHandler.ThrowOnFailure(OpenItem(child.ID, ref view, IntPtr.Zero, out frame));
                            }
                            else
                            {
                                ErrorHandler.ThrowOnFailure(OpenItemWithSpecific(child.ID, editorFlags, ref editorType,
                                    physicalView, ref logicalView, IntPtr.Zero, out frame));
                            }

                            // Show the window frame in the UI and make it the active window
                            if (frame != null)
                            {
                                ErrorHandler.ThrowOnFailure(frame.Show());
                            }
                        }
                    }
                }
            }

            return VSConstants.S_OK;
        }
ProjectNode