int IVsQueryEditQuerySave2.QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult)
        {
            this.createRequested.AddRange(rgpszMkDocuments);
            pdwQSResult = (uint)(this.QuerySaveFilesVerification?.Invoke((VsQuerySaveFlags)rgfQuerySave) ?? tagVSQuerySaveResult.QSR_SaveOK);

            return VSConstants.S_OK;
        }
        int IVsQueryEditQuerySave2.QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo)
        {
            this.editRequested.AddRange(rgpszMkDocuments);
            pfEditVerdict = (uint)this.QueryEditFilesVerdict;
            prgfMoreInfo = this.QueryEditFilesMoreInfo;

            Assert.AreEqual(this.VerifyQueryEditFlags, rgfQueryEdit, "Unexpected flags: " + ((VsQueryEditFlags)rgfQueryEdit).ToString());

            return VSConstants.S_OK;
        }
        int IVsQueryEditQuerySave2.QuerySaveFiles(uint saveFlags, int fileCount, string[] fileNames, uint[] fileFlags, VSQEQS_FILE_ATTRIBUTE_DATA[] fileInfos, out uint saveResult)
        {
            int result = VSConstants.S_OK;
            saveResult = 0;

            if (this.QuerySaveFiles != null)
            {
                tagVSQuerySaveResult callbackSaveResult;
                result = this.QuerySaveFiles((tagVSQuerySaveFlags)saveFlags, fileCount, fileNames, fileFlags, fileInfos, out callbackSaveResult);
                saveResult = (uint)callbackSaveResult;
            }

            return result;
        }
        int IVsQueryEditQuerySave2.QueryEditFiles(uint editFlags, int fileCount, string[] fileNames, uint[] fileFlags, VSQEQS_FILE_ATTRIBUTE_DATA[] fileInfos, out uint editResult, out uint moreInfo)
        {
            int result = VSConstants.S_OK;
            editResult = 0;
            moreInfo = 0;

            if (this.QueryEditFiles != null)
            {
                tagVSQueryEditResult callbackEditResult;
                tagVSQueryEditResultFlags callbackMoreInfo;
                result = this.QueryEditFiles((tagVSQueryEditFlags)editFlags, fileCount, fileNames, fileFlags, fileInfos, out callbackEditResult, out callbackMoreInfo);
                editResult = (uint)callbackEditResult;
                moreInfo = (uint)callbackMoreInfo;
            }

            return result;
        }
示例#5
0
        public int QuerySaveFile2(string pszMkDocument, uint[] rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult, out uint prgfMoreInfo)
        {
            prgfMoreInfo = (uint)tagVSQuerySaveResultFlags.QSR_DefaultFlag;
            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;

            //HACK: this really shouldnt be done this way as we are refreshing all icons everytime one file is edited

            Func<VSITEMSELECTION, bool> where = delegate(VSITEMSELECTION item)
            {
                string name;
                item.pHier.GetCanonicalName(item.itemid, out name);
                return pszMkDocument.ToLower() == name;
            };
            var nodes = this.GetAllItems(where);
            RefreshGlyphs(nodes);

            return VSConstants.S_OK;
        }
 // TODO: Implement IVsQueryEditQuerySave3 extra's.
 /// <summary>
 /// Notifies the environment that a file is about to be saved.
 /// </summary>
 /// <param name="pszMkDocument">The PSZ mk document.</param>
 /// <param name="rgf">The RGF.</param>
 /// <param name="pFileInfo">The p file info.</param>
 /// <param name="pdwQSResult">The PDW QS result.</param>
 /// <param name="prgfMoreInfo">The PRGF more info.</param>
 /// <returns></returns>
 public int QuerySaveFile2(string pszMkDocument, uint[] rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult, out uint prgfMoreInfo)
 {
     pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
     prgfMoreInfo = (uint)tagVSQuerySaveResultFlags.QSR_DefaultFlag;
     return VSConstants.S_OK;
 }
 /// <summary>
 /// Notifies the environment that a file is about to be saved.
 /// </summary>
 /// <param name="pszMkDocument">The document that wants to be saved</param>
 /// <param name="rgf">Valid file attributes?</param>
 /// <param name="pFileInfo">File attributes</param>
 /// <param name="pdwQSResult">Result</param>
 /// <returns></returns>
 public int QuerySaveFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult)
 {
     return QuerySaveFiles(
         (uint)tagVSQuerySaveFlags.QSF_DefaultOperation,
         1,
         new string[] { pszMkDocument },
         null,
         null,
         out pdwQSResult);
 }
        /// <summary>
        /// Synchronizes or refreshes the file date and size after an editor saves an unreloadable file.
        /// </summary>
        /// <param name="pszMkDocument">The PSZ mk document.</param>
        /// <param name="rgf">The RGF.</param>
        /// <param name="pFileInfo">The p file info.</param>
        /// <returns></returns>
        public int OnAfterSaveUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo)
        {
            if (IsSafeSccPath(pszMkDocument))
                MarkDirty(pszMkDocument);

            return VSConstants.S_OK;
        }
        /// <summary>
        /// Notifies the environment that multiple files are about to be saved.
        /// </summary>
        /// <param name="rgfQuerySave">The RGF query save.</param>
        /// <param name="cFiles">The c files.</param>
        /// <param name="rgpszMkDocuments">The RGPSZ mk documents.</param>
        /// <param name="rgrgf">The RGRGF.</param>
        /// <param name="rgFileInfo">The rg file info.</param>
        /// <param name="pdwQSResult">The PDW QS result.</param>
        /// <returns></returns>
        public int QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult)
        {
            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
            bool silent = (rgfQuerySave & (uint)tagVSQuerySaveFlags.QSF_SilentMode) != 0;

            if (rgpszMkDocuments == null)
                return VSConstants.E_POINTER;

            if (_querySaveBatchCancel)
            {
                pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
                return VSConstants.S_OK;
            }

            try
            {
                bool saveAs = false;
                bool saveOk = false;

                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue;

                    file = GitTools.GetNormalizedFullPath(file);

                    GitItem item = StatusCache[file];
                    if (!item.IsReadOnly)
                        continue;
                    else if (silent)
                    {
                        pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_NoisyPromptRequired;
                        return VSConstants.S_OK;
                    }

                    tagVSQuerySaveResult rslt = QueryReadOnlyFile(item);
                    switch (rslt)
                    {
                        case tagVSQuerySaveResult.QSR_NoSave_Cancel:
                            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
                            if (IsInSaveBatch)
                                _querySaveBatchCancel = true;
                            return VSConstants.S_OK;
                        case tagVSQuerySaveResult.QSR_ForceSaveAs:
                            saveAs = true;
                            break;
                        case tagVSQuerySaveResult.QSR_SaveOK:
                            saveOk = true;
                            break;
                        default:
                            throw new InvalidOperationException();
                    }
                }

                if (saveAs && !saveOk)
                    pdwQSResult = (uint)tagVSQuerySaveResult.QSR_ForceSaveAs;
                else
                    pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;

                return VSConstants.S_OK;
            }
            finally
            {
                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue;

                    MarkDirty(GitTools.GetNormalizedFullPath(file));
                }
            }
        }
 public int QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult) {
     pdwQSResult = 0;
     return VSConstants.S_OK;
 }
示例#11
0
 public int OnAfterSaveUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo) {
     throw new NotImplementedException();
 }
 int IVsQueryEditQuerySave2.OnAfterSaveUnreloadableFile(string fileName, uint fileFlags, VSQEQS_FILE_ATTRIBUTE_DATA[] fileInfo)
 {
     throw new NotImplementedException();
 }
 int IVsQueryEditQuerySave2.QuerySaveFile(string fileName, uint fileFlags, VSQEQS_FILE_ATTRIBUTE_DATA[] fileInfo, out uint saveResult)
 {
     throw new NotImplementedException();
 }
 public int QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo) {
     prgfMoreInfo = 0;
     pfEditVerdict = 0;
     return VSConstants.S_OK;
 }
示例#15
0
 public int QuerySaveFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult) {
     throw new NotImplementedException();
 }
 public int QuerySaveFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult) {
     
     if (Path.GetFileNameWithoutExtension(pszMkDocument) == "FailSave") {
         pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
     } else {
         pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
     }
     return VSConstants.S_OK;
 }
示例#17
0
 public int QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult) {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Called by projects and editors before modifying a file
        /// The function allows the source control systems to take the necessary actions (checkout, flip attributes)
        /// to make the file writable in order to allow the edit to continue
        ///
        /// There are a lot of cases to deal with during QueryEdit/QuerySave. 
        /// - called in commmand line mode, when UI cannot be displayed
        /// - called during builds, when save shoudn't probably be allowed
        /// - called during projects migration, when projects are not open and not registered yet with source control
        /// - checking out files may bring new versions from vss database which may be reloaded and the user may lose in-memory changes; some other files may not be reloadable
        /// - not all editors call QueryEdit when they modify the file the first time (buggy editors!), and the files may be already dirty in memory when QueryEdit is called
        /// - files on disk may be modified outside IDE and may have attributes incorrect for their scc status
        /// - checkouts may fail
        /// </summary>
        /// <param name="rgfQueryEdit">The RGF query edit.</param>
        /// <param name="cFiles">The c files.</param>
        /// <param name="rgpszMkDocuments">The RGPSZ mk documents.</param>
        /// <param name="rgrgf">The RGRGF.</param>
        /// <param name="rgFileInfo">The rg file info.</param>
        /// <param name="pfEditVerdict">The pf edit verdict.</param>
        /// <param name="prgfMoreInfo">The PRGF more info.</param>
        /// <returns></returns>
        public int QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo)
        {
            tagVSQueryEditFlags queryFlags = (tagVSQueryEditFlags)rgfQueryEdit;
            pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditOK;
            prgfMoreInfo = (uint)(tagVSQueryEditResultFlags)0; // Must be 0 when verdict is QER_EditOK or you see failures like issue #624

            bool allowUI = (queryFlags & (tagVSQueryEditFlags.QEF_SilentMode | tagVSQueryEditFlags.QEF_ReportOnly | tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting)) == 0;

            bool? allowReadOnlyNonSccWrites = null;

            if (rgpszMkDocuments == null)
                return VSConstants.E_POINTER;

            try
            {
                // If the editor asks us to do anything in our power to make it editable
                // without prompting, just make those files writable.
                if ((queryFlags & tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting) != 0)
                    return QueryEditForceWritable(rgpszMkDocuments);

                HybridCollection<string> readOnlyEditFiles = null;
                List<GitItem> readOnlyItems = null;

                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue; // Skip non scc paths (Includes %TEMP%\*)

                    file = GitTools.GetNormalizedFullPath(file);

                    Monitor.ScheduleDirtyCheck(file);

                    GitItem item = StatusCache[file];

                    if (item.IsReadOnly)
                    {
                        if (!allowReadOnlyNonSccWrites.HasValue)
                            allowReadOnlyNonSccWrites = AllowReadOnlyNonSccWrites();

                        if (!allowReadOnlyNonSccWrites.Value)
                        {
                            if (!allowUI)
                            {
                                pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                                prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_InMemoryEditNotAllowed
                                                       | tagVSQueryEditResultFlags.QER_ReadOnlyNotUnderScc
                                                       | tagVSQueryEditResultFlags.QER_NoisyPromptRequired);

                                return VSConstants.S_OK;
                            }

                            if (readOnlyEditFiles == null)
                            {
                                readOnlyEditFiles = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase);
                                readOnlyItems = new List<GitItem>();
                            }

                            if (!readOnlyEditFiles.Contains(item.FullPath))
                            {
                                readOnlyEditFiles.Add(item.FullPath);
                                readOnlyItems.Add(item);
                            }
                        }
                        // else // allow editting
                    }
                }
                if (readOnlyItems != null)
                {
                    // TODO: Handle multiple items correctly
                    // Is this only for non-scc items or also for scc items that are readonly for other reasons?
                    CommandResult result =
                        CommandService.DirectlyExecCommand(VisualGitCommand.MakeNonSccFileWriteable, readOnlyItems[0], CommandPrompt.DoDefault);

                    bool allowed = result.Result is bool ? (bool)result.Result : false;

                    if (!allowed)
                    {
                        pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                        prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_InMemoryEditNotAllowed
                                               | tagVSQueryEditResultFlags.QER_ReadOnlyNotUnderScc // TODO: Specialize to SCC?
                                               );
                    }
                }
            }
            catch (Exception ex)
            {
                IVisualGitErrorHandler eh = GetService<IVisualGitErrorHandler>();

                if (eh != null && eh.IsEnabled(ex))
                    eh.OnError(ex);
                else
                    throw;
            }

            return VSConstants.S_OK;
        }
示例#19
0
 int IVsQueryEditQuerySave2.DeclareUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo)
 {
     return VSConstants.S_OK;
 }
        /// <summary>
        /// States that a file will not be reloaded if it changes on disk
        /// </summary>
        /// <param name="pszMkDocument">The PSZ mk document.</param>
        /// <param name="rgf">The RGF.</param>
        /// <param name="pFileInfo">The p file info.</param>
        /// <returns></returns>
        public int DeclareUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo)
        {
            if (!string.IsNullOrEmpty(pszMkDocument))
                lock (_unreloadable)
                {
                    int n;

                    if (!_unreloadable.TryGetValue(pszMkDocument, out n))
                        n = 0;

                    n++;

                    if (n != 0)
                        _unreloadable[pszMkDocument] = n;
                    else
                        _unreloadable.Remove(pszMkDocument);
                }

            return VSConstants.S_OK;
        }
示例#21
0
 int IVsQueryEditQuerySave2.QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo)
 {
     pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditOK;
     prgfMoreInfo = 0;
     return VSConstants.S_OK;
 }
        /// <summary>
        /// Called by projects and editors before modifying a file
        /// The function allows the source control systems to take the necessary actions (checkout, flip attributes)
        /// to make the file writable in order to allow the edit to continue
        ///
        /// There are a lot of cases to deal with during QueryEdit/QuerySave. 
        /// - called in commmand line mode, when UI cannot be displayed
        /// - called during builds, when save shoudn't probably be allowed
        /// - called during projects migration, when projects are not open and not registered yet with source control
        /// - checking out files may bring new versions from vss database which may be reloaded and the user may lose in-memory changes; some other files may not be reloadable
        /// - not all editors call QueryEdit when they modify the file the first time (buggy editors!), and the files may be already dirty in memory when QueryEdit is called
        /// - files on disk may be modified outside IDE and may have attributes incorrect for their scc status
        /// - checkouts may fail
        /// </summary>
        /// <param name="rgfQueryEdit">The RGF query edit.</param>
        /// <param name="cFiles">The c files.</param>
        /// <param name="rgpszMkDocuments">The RGPSZ mk documents.</param>
        /// <param name="rgrgf">The RGRGF.</param>
        /// <param name="rgFileInfo">The rg file info.</param>
        /// <param name="pfEditVerdict">The pf edit verdict.</param>
        /// <param name="prgfMoreInfo">The PRGF more info.</param>
        /// <returns></returns>
        public int QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo)
        {
            tagVSQueryEditFlags queryFlags = (tagVSQueryEditFlags)rgfQueryEdit;
            pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditOK;
            prgfMoreInfo = (uint)(tagVSQueryEditResultFlags)0; // Must be 0 when verdict is QER_EditOK or you see failures like issue #624

            bool allowUI = (queryFlags & (tagVSQueryEditFlags.QEF_SilentMode | tagVSQueryEditFlags.QEF_ReportOnly | tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting)) == 0;

            bool? allowReadOnlyNonSccWrites = null;

            if (rgpszMkDocuments == null)
                return VSConstants.E_POINTER;

            try
            {
                // If the editor asks us to do anything in our power to make it editable
                // without prompting, just make those files writable.
                if ((queryFlags & tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting) != 0)
                    return QueryEditForceWritable(rgpszMkDocuments);

                HybridCollection<string> mustLockFiles = null;
                HybridCollection<string> readOnlyEditFiles = null;
                List<SvnItem> mustLockItems = null;
                List<SvnItem> readOnlyItems = null;

                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue; // Skip non scc paths (Includes %TEMP%\*)

                    file = SvnTools.GetNormalizedFullPath(file);

                    Monitor.ScheduleDirtyCheck(file);

                    SvnItem item = StatusCache[file];

                    if (item.IsReadOnlyMustLock && !item.IsDirectory)
                    {
                        if (!allowUI)
                        {
                            pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                            prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_ReadOnlyUnderScc
                                                   | tagVSQueryEditResultFlags.QER_NoisyCheckoutRequired);

                            return VSConstants.S_OK;
                        }

                        if (mustLockItems == null)
                        {
                            mustLockFiles = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase);
                            mustLockItems = new List<SvnItem>();
                        }

                        if (!mustLockFiles.Contains(item.FullPath))
                        {
                            mustLockFiles.Add(item.FullPath);
                            mustLockItems.Add(item);
                        }
                    }
                    else if (item.IsReadOnly)
                    {
                        if (!allowReadOnlyNonSccWrites.HasValue)
                            allowReadOnlyNonSccWrites = AllowReadOnlyNonSccWrites();

                        if (!allowReadOnlyNonSccWrites.Value)
                        {
                            if (!allowUI)
                            {
                                pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                                prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_InMemoryEditNotAllowed
                                                       | tagVSQueryEditResultFlags.QER_ReadOnlyNotUnderScc
                                                       | tagVSQueryEditResultFlags.QER_NoisyPromptRequired);

                                return VSConstants.S_OK;
                            }

                            if (readOnlyEditFiles == null)
                            {
                                readOnlyEditFiles = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase);
                                readOnlyItems = new List<SvnItem>();
                            }

                            if (!readOnlyEditFiles.Contains(item.FullPath))
                            {
                                readOnlyEditFiles.Add(item.FullPath);
                                readOnlyItems.Add(item);
                            }
                        }
                        // else // allow editting
                    }
                }
                if (mustLockItems != null)
                {
                    List<SvnItem> mustBeLocked = new List<SvnItem>(mustLockItems);

                    // Look at all subfiles of the must be locked document and add these to the dialog
                    // to make it easier to lock them too
                    foreach (string lockFile in new List<string>(mustLockFiles))
                    {
                        foreach (SvnItem item in GetAllDocumentItems(lockFile))
                        {
                            if (!mustLockFiles.Contains(item.FullPath))
                            {
                                mustLockFiles.Add(item.FullPath);
                                mustLockItems.Add(item);
                            }
                        }
                    }

                    CommandService.DirectlyExecCommand(AnkhCommand.SccLock, mustLockItems, CommandPrompt.DoDefault);
                    // Only check the original list; the rest of the items in mustLockItems is optional
                    foreach (SvnItem i in mustBeLocked)
                    {
                        if (i.IsReadOnlyMustLock)
                        {
                            // User has probably canceled the lock operation, or it failed.
                            pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                            prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_CheckoutCanceledOrFailed
                                | tagVSQueryEditResultFlags.QER_ReadOnlyUnderScc);
                            break;
                        }
                    }
                }
                if (readOnlyItems != null)
                {
                    // TODO: Handle multiple items correctly
                    // Is this only for non-scc items or also for scc items that are readonly for other reasons?
                    CommandResult result =
                        CommandService.DirectlyExecCommand(AnkhCommand.MakeNonSccFileWriteable, readOnlyItems[0], CommandPrompt.DoDefault);

                    bool allowed = result.Result is bool ? (bool)result.Result : false;

                    if (!allowed)
                    {
                        pfEditVerdict = (uint)tagVSQueryEditResult.QER_EditNotOK;
                        prgfMoreInfo = (uint)(tagVSQueryEditResultFlags.QER_InMemoryEditNotAllowed
                                               | tagVSQueryEditResultFlags.QER_ReadOnlyNotUnderScc // TODO: Specialize to SCC?
                                               );
                    }
                }
            }
            catch (Exception ex)
            {
                IAnkhErrorHandler eh = GetService<IAnkhErrorHandler>();

                if (eh != null && eh.IsEnabled(ex))
                    eh.OnError(ex);
                else
                    throw;
            }

            return VSConstants.S_OK;
        }
示例#23
0
 int IVsQueryEditQuerySave2.QuerySaveFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo, out uint pdwQSResult)
 {
     OnFileSave(pszMkDocument);
     pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
     return VSConstants.S_OK;
 }
        /// <summary>
        /// Notifies the environment that multiple files are about to be saved.
        /// </summary>
        /// <param name="rgfQuerySave">The RGF query save.</param>
        /// <param name="cFiles">The c files.</param>
        /// <param name="rgpszMkDocuments">The RGPSZ mk documents.</param>
        /// <param name="rgrgf">The RGRGF.</param>
        /// <param name="rgFileInfo">The rg file info.</param>
        /// <param name="pdwQSResult">The PDW QS result.</param>
        /// <returns></returns>
        public int QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult)
        {
            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
            bool silent = (rgfQuerySave & (uint)tagVSQuerySaveFlags.QSF_SilentMode) != 0;

            List<SvnItem> toBeSvnLocked = new List<SvnItem>();

            if (rgpszMkDocuments == null)
                return VSConstants.E_POINTER;

            if (_querySaveBatchCancel)
            {
                pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
                return VSConstants.S_OK;
            }

            try
            {
                bool saveAs = false;
                bool saveOk = false;

                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue;

                    file = SvnTools.GetNormalizedFullPath(file);

                    SvnItem item = StatusCache[file];
                    if (item.IsReadOnlyMustLock)
                    {
                        if (silent)
                        {
                            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_NoisyPromptRequired;
                            return VSConstants.S_OK;
                        }
                        toBeSvnLocked.Add(item);
                        continue;
                    }
                    else if (!item.IsReadOnly)
                        continue;
                    else if (silent)
                    {
                        pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_NoisyPromptRequired;
                        return VSConstants.S_OK;
                    }

                    tagVSQuerySaveResult rslt = QueryReadOnlyFile(item);
                    switch (rslt)
                    {
                        case tagVSQuerySaveResult.QSR_NoSave_Cancel:
                            pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
                            if (IsInSaveBatch)
                                _querySaveBatchCancel = true;
                            return VSConstants.S_OK;
                        case tagVSQuerySaveResult.QSR_ForceSaveAs:
                            saveAs = true;
                            break;
                        case tagVSQuerySaveResult.QSR_SaveOK:
                            saveOk = true;
                            break;
                        default:
                            throw new InvalidOperationException();
                    }
                }

                if (saveAs && !saveOk)
                    pdwQSResult = (uint)tagVSQuerySaveResult.QSR_ForceSaveAs;
                else
                    pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;

                if (toBeSvnLocked.Count > 0)
                {
                    // File(s) need to be locked
                    CommandService.DirectlyExecCommand(AnkhCommand.SccLock, toBeSvnLocked.ToArray());

                    bool notWritable = false;
                    foreach (SvnItem item in toBeSvnLocked)
                    {
                        if (item.IsReadOnlyMustLock)
                            notWritable = true;
                    }

                    if (notWritable)
                        pdwQSResult = (uint)tagVSQuerySaveResult.QSR_NoSave_Cancel;
                }

                return VSConstants.S_OK;
            }
            finally
            {
                for (int i = 0; i < cFiles; i++)
                {
                    string file = rgpszMkDocuments[i];

                    if (!IsSafeSccPath(file))
                        continue;

                    MarkDirty(SvnTools.GetNormalizedFullPath(file));
                }
            }
        }
示例#25
0
 int IVsQueryEditQuerySave2.QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult)
 {
     OnFileSave(rgpszMkDocuments);
     pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
     return VSConstants.S_OK;
 }
示例#26
0
        /// <summary>
        /// Verify if the file can be written to.
        /// Return false if the file is read only and/or not checked out
        /// and the user did not give permission to change it.
        /// Note that exact behavior can also be affected based on the SCC
        /// settings under Tools->Options.
        /// </summary>
        internal bool QueryEditProjectFile(bool suppressUI)
        {
            bool result = true;
            if (this.site == null)
            {
                // We're already zombied. Better return FALSE.
                result = false;
            }
            else if (this.disableQueryEdit)
            {
                return true;
            }
            else
            {
                IVsQueryEditQuerySave2 queryEditQuerySave = this.GetService(typeof(SVsQueryEditQuerySave)) as IVsQueryEditQuerySave2;
                if (queryEditQuerySave != null)
                {   // Project path dependends on server/client project
                    string path = this.filename;

                    tagVSQueryEditFlags qef = tagVSQueryEditFlags.QEF_AllowInMemoryEdits;
                    if (suppressUI)
                        qef |= tagVSQueryEditFlags.QEF_SilentMode;

                    // If we are debugging, we want to prevent our project from being reloaded. To
                    // do this, we pass the QEF_NoReload flag
                    if (!Utilities.IsVisualStudioInDesignMode(this.Site))
                        qef |= tagVSQueryEditFlags.QEF_NoReload;

                    uint verdict;
                    uint moreInfo;
                    string[] files = new string[1];
                    files[0] = path;
                    uint[] flags = new uint[1];
                    VSQEQS_FILE_ATTRIBUTE_DATA[] attributes = new VSQEQS_FILE_ATTRIBUTE_DATA[1];
                    int hr = queryEditQuerySave.QueryEditFiles(
                                    (uint)qef,
                                    1, // 1 file
                                    files, // array of files
                                    flags, // no per file flags
                                    attributes, // no per file file attributes
                                    out verdict,
                                    out moreInfo /* ignore additional results */);

                    tagVSQueryEditResult qer = (tagVSQueryEditResult)verdict;
                    if (ErrorHandler.Failed(hr) || (qer != tagVSQueryEditResult.QER_EditOK))
                    {
                        if (!suppressUI && !Utilities.IsInAutomationFunction(this.Site))
                        {
                            string message = SR.GetString(SR.CancelQueryEdit, path);
                            string title = string.Empty;
                            OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
                            OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                            OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                            VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                        }
                        result = false;
                    }
                }
            }
            return result;
        }
 public int OnAfterSaveUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo) {
     return VSConstants.S_OK;
 }
示例#28
0
 public int QuerySaveFiles2(uint[] rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQSResult, out uint prgfMoreInfo)
 {
     prgfMoreInfo = (uint)tagVSQuerySaveResultFlags.QSR_DefaultFlag;
     pdwQSResult = (uint)tagVSQuerySaveResult.QSR_SaveOK;
     return VSConstants.S_OK;
 }
 int IVsQueryEditQuerySave2.DeclareUnreloadableFile(string pszMkDocument, uint rgf, VSQEQS_FILE_ATTRIBUTE_DATA[] pFileInfo)
 {
     throw new NotImplementedException();
 }