public virtual int SaveItem()

in Nodejs/Product/Nodejs/SharedProject/ProjectNode.cs [6752:6869]


        public virtual int SaveItem(VSSAVEFLAGS saveFlag, string silentSaveAsName, uint itemid, IntPtr docData, out int cancelled)
        {
            cancelled = 0;

            // Validate itemid 
            if (itemid == VSConstants.VSITEMID_ROOT || itemid == VSConstants.VSITEMID_SELECTION)
            {
                return VSConstants.E_INVALIDARG;
            }

            var node = this.NodeFromItemId(itemid);
            if (node == null)
            {
                return VSConstants.E_FAIL;
            }

            var existingFileMoniker = node.GetMkDocument();

            // We can only perform save if the document is open
            if (docData == IntPtr.Zero)
            {
                throw new InvalidOperationException(SR.GetString(SR.CanNotSaveFileNotOpeneInEditor, node.Url));
            }

            var docNew = string.Empty;
            var returnCode = VSConstants.S_OK;
            IPersistFileFormat ff = null;
            IVsPersistDocData dd = null;
            var shell = this.Site.GetService(typeof(SVsUIShell)) as IVsUIShell;
            Utilities.CheckNotNull(shell);

            try
            {
                //Save docdata object. 
                //For the saveas action a dialog is show in order to enter new location of file.
                //In case of a save action and the file is readonly a dialog is also shown
                //with a couple of options, SaveAs, Overwrite or Cancel.
                ff = Marshal.GetObjectForIUnknown(docData) as IPersistFileFormat;
                Utilities.CheckNotNull(ff);

                if (VSSAVEFLAGS.VSSAVE_SilentSave == saveFlag)
                {
                    ErrorHandler.ThrowOnFailure(shell.SaveDocDataToFile(saveFlag, ff, silentSaveAsName, out docNew, out cancelled));
                }
                else
                {
                    dd = Marshal.GetObjectForIUnknown(docData) as IVsPersistDocData;
                    Utilities.CheckNotNull(dd);

                    ErrorHandler.ThrowOnFailure(dd.SaveDocData(saveFlag, out docNew, out cancelled));
                }

                // We can be unloaded after the SaveDocData() call if the save caused a designer to add a file and this caused
                // the project file to be reloaded (QEQS caused a newer version of the project file to be downloaded). So we check
                // here.
                if (this.IsClosed)
                {
                    cancelled = 1;
                    return (int)OleConstants.OLECMDERR_E_CANCELED;
                }
                else
                {
                    // if a SaveAs occurred we need to update to the fact our item's name has changed.
                    // this includes the following:
                    //    1. call RenameDocument on the RunningDocumentTable
                    //    2. update the full path name for the item in our hierarchy
                    //    3. a directory-based project may need to transfer the open editor to the
                    //       MiscFiles project if the new file is saved outside of the project directory.
                    //       This is accomplished by calling IVsExternalFilesManager::TransferDocument                    

                    // we have three options for a saveas action to be performed
                    // 1. the flag was set (the save as command was triggered)
                    // 2. a silent save specifying a new document name
                    // 3. a save command was triggered but was not possible because the file has a read only attrib. Therefore
                    //    the user has chosen to do a save as in the dialog that showed up
                    var emptyOrSamePath = string.IsNullOrEmpty(docNew) || CommonUtils.IsSamePath(existingFileMoniker, docNew);
                    var saveAs = ((saveFlag == VSSAVEFLAGS.VSSAVE_SaveAs)) ||
                        ((saveFlag == VSSAVEFLAGS.VSSAVE_SilentSave) && !emptyOrSamePath) ||
                        ((saveFlag == VSSAVEFLAGS.VSSAVE_Save) && !emptyOrSamePath);

                    if (saveAs)
                    {
                        returnCode = node.AfterSaveItemAs(docData, docNew);

                        // If it has been cancelled recover the old name.
                        if ((returnCode == (int)OleConstants.OLECMDERR_E_CANCELED || returnCode == VSConstants.E_ABORT))
                        {
                            // Cleanup.
                            this.DeleteFromStorage(docNew);

                            if (ff != null)
                            {
                                returnCode = shell.SaveDocDataToFile(VSSAVEFLAGS.VSSAVE_SilentSave, ff, existingFileMoniker, out docNew, out cancelled);
                            }
                        }
                        else if (returnCode != VSConstants.S_OK)
                        {
                            ErrorHandler.ThrowOnFailure(returnCode);
                        }
                    }
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception :" + e.Message);
                returnCode = e.ErrorCode;

                // Try to recover
                // changed from MPFProj:
                // http://mpfproj10.codeplex.com/WorkItem/View.aspx?WorkItemId=6982
                if (ff != null && cancelled == 0)
                {
                    ErrorHandler.ThrowOnFailure(shell.SaveDocDataToFile(VSSAVEFLAGS.VSSAVE_SilentSave, ff, existingFileMoniker, out docNew, out cancelled));
                }
            }

            return returnCode;
        }