Esempio n. 1
0
        public bool CanAddFiles(string[] files)
        {
            int len = files.Length;

            VSQUERYADDFILEFLAGS[] flags = new VSQUERYADDFILEFLAGS[len];
            try  {
                for (int i = 0; i < files.Length; i++)
                {
                    flags[i] = VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags;
                }
                foreach (IVsTrackProjectDocumentsEvents2 sink in this.trackProjectEventSinks)
                {
                    VSQUERYADDFILERESULTS[] summary = new VSQUERYADDFILERESULTS[1];
                    sink.OnQueryAddFiles((IVsProject)this, len, files, flags, summary, null);
                    if (summary[0] == VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK)
                    {
                        return(false);
                    }
                }
                return(true);
            }
            catch  {
                return(false);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Asks the environment for permission to add files.
        /// </summary>
        /// <param name="files">The files to add.</param>
        /// <param name="flags">The VSQUERYADDFILEFLAGS flags associated to the files added</param>
        /// <returns>true if the file can be added, false if not.</returns>
        internal bool CanAddItems(string[] files, VSQUERYADDFILEFLAGS[] flags)
        {
            // If we are silent then we assume that the file can be added, since we do not want to trigger this event.
            if ((this.projectMgr.EventTriggeringFlag & ProjectNode.EventTriggering.DoNotTriggerTrackerEvents) != 0)
            {
                return(true);
            }

            if (files == null || files.Length == 0)
            {
                return(false);
            }
            ThreadHelper.ThrowIfNotOnUIThread();

            int len = files.Length;

            VSQUERYADDFILERESULTS[] summary = new VSQUERYADDFILERESULTS[1];
            ErrorHandler.ThrowOnFailure(this.GetIVsTrackProjectDocuments2().OnQueryAddFiles(this.projectMgr, len, files, flags, summary, null));
            if (summary[0] == VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 3
0
 public bool CanAddFiles(string[] files) {
     int len = files.Length;
     VSQUERYADDFILEFLAGS[] flags = new VSQUERYADDFILEFLAGS[len];
     try {
         for (int i = 0; i < files.Length; i++)
             flags[i] = VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags;
         foreach (IVsTrackProjectDocumentsEvents2 sink in this.trackProjectEventSinks) {
             VSQUERYADDFILERESULTS[] summary = new VSQUERYADDFILERESULTS[1];
             NativeMethods.ThrowOnFailure(sink.OnQueryAddFiles((IVsProject)this, len, files, flags, summary, null));
             if (summary[0] == VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK)
                 return false;
         }
         return true;
     } catch {
         return false;
     }
 }
        /// <summary>
        /// Asks the environment for permission to add files.
        /// </summary>
        /// <param name="files">The files to add.</param>
        /// <param name="flags">The VSQUERYADDFILEFLAGS flags associated to the files added</param>
        /// <returns>true if the file can be added, false if not.</returns>
        internal bool CanAddItems(string[] files, VSQUERYADDFILEFLAGS[] flags) {
            // If we are silent then we assume that the file can be added, since we do not want to trigger this event.
            if ((this.projectMgr.EventTriggeringFlag & ProjectNode.EventTriggering.DoNotTriggerTrackerEvents) != 0) {
                return true;
            }

            if (files == null || files.Length == 0) {
                return false;
            }

            int len = files.Length;
            VSQUERYADDFILERESULTS[] summary = new VSQUERYADDFILERESULTS[1];
            ErrorHandler.ThrowOnFailure(this.GetIVsTrackProjectDocuments2().OnQueryAddFiles(projectMgr.GetOuterInterface<IVsProject>(), len, files, flags, summary, null));
            if (summary[0] == VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK) {
                return false;
            }

            return true;
        }
Esempio n. 5
0
        /// <summary>
        /// Asks the environment for permission to add files.
        /// </summary>
        /// <param name="files">The files to add.</param>
        /// <param name="flags">The VSQUERYADDFILEFLAGS flags associated to the files added</param>
        /// <returns>true if the file can be added, false if not.</returns>
        public virtual bool CanAddItems(string[] files, VSQUERYADDFILEFLAGS[] flags)
        {
            // If we are silent then we assume that the file can be added, since we do not want to trigger this event.
            if ((this.projectMgr.EventTriggeringFlag & SuppressEvents.Tracker) != 0)
            {
                return(true);
            }

            if (files == null || files.Length == 0)
            {
                return(false);
            }

            int len = files.Length;

            VSQUERYADDFILERESULTS[] summary = new VSQUERYADDFILERESULTS[1];
            ErrorHandler.ThrowOnFailure(this.GetIVsTrackProjectDocuments2().OnQueryAddFiles(this.projectMgr.InteropSafeIVsProject3, len, files, flags, summary, null));
            if (summary[0] == VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 6
0
 int IVsTrackProjectDocumentsEvents2.OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
 {
     return NativeMethods.S_OK; // We are not interested in this one
 }
        public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags,
            VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            pSummaryResult[0] = VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK;
            if (rgResults != null)
            {
                for (int iFile = 0; iFile < cFiles; iFile++)
                {
                    rgResults[iFile] = VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK;
                }
            }

            try
            {
                var sccProject = pProject as IVsSccProject2;
                var pHier = pProject as IVsHierarchy;
                string projectName = null;
                if (sccProject == null)
                {
                    // This is the solution calling
                    pHier = (IVsHierarchy) _sccProvider.GetService(typeof (SVsSolution));
                }

                if (sccProject != null)
                {
                   for (int iFile = 0; iFile < cFiles; iFile++)
					{
                        _fileCache.AddFile(rgpszMkDocuments[iFile], sccProject);
                    } 
                }
             
            }
            catch (Exception)
            {
            }


            return VSConstants.E_NOTIMPL;
        }
        public void TestTPDEvents()
        {
            int result = 0;

            SccProviderService target = GetSccProviderServiceInstance;

            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());

            solution.AddProject(project);

            Hashtable uncontrolled = new Hashtable();

            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);
            // In real live, a QueryEdit call on the project file would be necessary to add/rename/delete items

            // Add a new item and fire the appropriate events
            string pendingAddFile = Path.GetTempFileName();

            VSQUERYADDFILERESULTS[] pSummaryResultAdd = new VSQUERYADDFILERESULTS[1];
            VSQUERYADDFILERESULTS[] rgResultsAdd      = new VSQUERYADDFILERESULTS[1];
            result = target.OnQueryAddFiles(project as IVsProject, 1, new string[] { pendingAddFile }, null, pSummaryResultAdd, rgResultsAdd);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            project.AddItem(pendingAddFile);
            result = target.OnAfterAddFilesEx(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, null);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);

            // Rename the item and verify the file remains is controlled
            string newName = pendingAddFile + ".renamed";

            VSQUERYRENAMEFILERESULTS[] pSummaryResultRen = new VSQUERYRENAMEFILERESULTS[1];
            VSQUERYRENAMEFILERESULTS[] rgResultsRen      = new VSQUERYRENAMEFILERESULTS[1];
            result = target.OnQueryRenameFiles(project as IVsProject, 1, new string[] { pendingAddFile }, new string[] { newName }, null, pSummaryResultRen, rgResultsRen);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            project.RenameItem(pendingAddFile, newName);
            result = target.OnAfterRenameFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, new string[] { newName }, new VSRENAMEFILEFLAGS[] { VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags });
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(newName), "Incorrect status returned");

            // Mock the UIShell service to answer Cancel to the dialog invocation
            BaseMock mockUIShell = MockUiShellProvider.GetShowMessageBoxCancel();

            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should not be allowed
            VSQUERYREMOVEFILERESULTS[] pSummaryResultDel = new VSQUERYREMOVEFILERESULTS[1];
            VSQUERYREMOVEFILERESULTS[] rgResultsDel      = new VSQUERYREMOVEFILERESULTS[1];
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveNotOK, pSummaryResultDel[0]);
            // Mock the UIShell service to answer Yes to the dialog invocation
            serviceProvider.RemoveService(typeof(IVsUIShell));
            mockUIShell = MockUiShellProvider.GetShowMessageBoxYes();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should be allowed this time
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK, pSummaryResultDel[0]);
            // Remove the file from project
            project.RemoveItem(newName);
            result = target.OnAfterRemoveFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { newName }, null);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
        }
 public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
 {
     throw new NotImplementedException();
 }
 public virtual int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
 {
     return VSConstants.E_NOTIMPL;
 }
 public int OnQueryAddFiles(IVsProject p, int length, string[] files,
                            VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult,
                            VSQUERYADDFILERESULTS[] rgResults)
 {
     try
     {
         EnvDTE.Project project = DTEUtil.GetProject(p as IVsHierarchy);
         if (DTEUtil.IsIceBuilderEnabled(project))
         {
             for (int i = 0; i < length; ++i)
             {
                 String path = files[i];
                 if(Path.GetExtension(path).Equals(".ice"))
                 {
                     if (!ProjectUtil.CheckGenerateFileIsValid(project, path))
                     {
                         pSummaryResult[i] = VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;
                     }
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Package.UnexpectedExceptionWarning(ex);
         throw;
     }
     return 0;
 }
        public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags,
            VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
        {
            var args = new QueryProjectAddFilesEventArgs(this.events)
            {
                Files = rgpszMkDocuments,
            };

            //VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK;
            //VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;

            this.events.TriggerQueryProjectAddFiles(args);

            return VSConstants.S_OK;
        }
 public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults) {
     foreach (var file in rgpszMkDocuments) {
         DocumentEvents.Add("OnQueryAddFiles " + file);
         CodeDocumentEvents.Add("OnQueryAddFiles(" + GetRelativePath(pProject, file) + ")");
     }
     return VSConstants.S_OK;
 }
        public void TestTPDEvents()
        {
            int result = 0;

            SccProviderService target = GetSccProviderServiceInstance;
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());
            solution.AddProject(project);

            Hashtable uncontrolled = new Hashtable();
            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);
            // In real live, a QueryEdit call on the project file would be necessary to add/rename/delete items

            // Add a new item and fire the appropriate events
            string pendingAddFile = Path.GetTempFileName();
            VSQUERYADDFILERESULTS[] pSummaryResultAdd = new VSQUERYADDFILERESULTS[1];
            VSQUERYADDFILERESULTS[] rgResultsAdd = new VSQUERYADDFILERESULTS[1];
            result = target.OnQueryAddFiles(project as IVsProject, 1, new string[] {pendingAddFile},  null, pSummaryResultAdd, rgResultsAdd);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            project.AddItem(pendingAddFile);
            result = target.OnAfterAddFilesEx(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, null);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);

            // Rename the item and verify the file remains is controlled
            string newName = pendingAddFile + ".renamed";
            VSQUERYRENAMEFILERESULTS[] pSummaryResultRen = new VSQUERYRENAMEFILERESULTS[1];
            VSQUERYRENAMEFILERESULTS[] rgResultsRen = new VSQUERYRENAMEFILERESULTS[1];
            result = target.OnQueryRenameFiles(project as IVsProject, 1, new string[] { pendingAddFile }, new string[] { newName }, null, pSummaryResultRen, rgResultsRen);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            project.RenameItem(pendingAddFile, newName);
            result = target.OnAfterRenameFiles(1, 1, new IVsProject[] {project as IVsProject}, new int[] {0}, new string[] { pendingAddFile }, new string[] { newName }, new VSRENAMEFILEFLAGS[] {VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags});
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(newName), "Incorrect status returned");

            // Mock the UIShell service to answer Cancel to the dialog invocation
            BaseMock mockUIShell = MockUiShellProvider.GetShowMessageBoxCancel();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should not be allowed
            VSQUERYREMOVEFILERESULTS[] pSummaryResultDel = new VSQUERYREMOVEFILERESULTS[1];
            VSQUERYREMOVEFILERESULTS[] rgResultsDel = new VSQUERYREMOVEFILERESULTS[1];
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveNotOK, pSummaryResultDel[0]);
            // Mock the UIShell service to answer Yes to the dialog invocation
            serviceProvider.RemoveService(typeof(IVsUIShell));
            mockUIShell = MockUiShellProvider.GetShowMessageBoxYes();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should be allowed this time
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK, pSummaryResultDel[0]);
            // Remove the file from project
            project.RemoveItem(newName);
            result = target.OnAfterRemoveFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { newName }, null);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
        }
Esempio n. 15
0
 public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults) {
     if (rgResults != null) {
         for (int i = 0; i < cFiles; i++) {
             rgResults[i] = VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK;
         }
     }
     if (pSummaryResult != null) {
         pSummaryResult[0] = VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK;
     }
     return VSConstants.S_OK;
 }
Esempio n. 16
0
 public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, 
                            VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, 
                            VSQUERYADDFILERESULTS[] rgResults)
 {
     return 0;
 }
Esempio n. 17
0
        /// <summary>
        /// This method notifies the client when a project has requested to add files.
        /// </summary>
        /// <param name="pProject"></param>
        /// <param name="cFiles"></param>
        /// <param name="rgpszMkDocuments"></param>
        /// <param name="rgFlags"></param>
        /// <param name="pSummaryResult"></param>
        /// <param name="rgResults"></param>
        /// <returns></returns>
        public int OnQueryAddFiles(IVsProject pProject, int cFiles, string[] rgpszMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
        {
            if (rgpszMkDocuments == null)
                return VSConstants.E_POINTER;

            RegisterForSccCleanup(); // Clear the origins
            _collectHints = true; // Some projects call HandsOff(file) on which files they wish to import. Use that to get more information

            bool allOk = true;

            bool track = SccProvider.TrackProjectChanges(pProject as IVsSccProject2);

            for (int i = 0; i < cFiles; i++)
            {
                bool ok = true;

                if (string.IsNullOrEmpty(rgpszMkDocuments[i]) || !SvnItem.IsValidPath(rgpszMkDocuments[i]))
                    continue;

                // TODO: Verify the new names do not give invalid Subversion state (Double casings, etc.)
                if (track && !SvnCanAddPath(SvnTools.GetNormalizedFullPath(rgpszMkDocuments[i]), SvnNodeKind.File))
                    ok = false;

                if (rgResults != null)
                    rgResults[i] = ok ? VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK : VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;

                if (!ok)
                    allOk = false;
            }

            if (pSummaryResult != null)
                pSummaryResult[0] = allOk ? VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK : VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;

            if (!allOk && !_inBatch)
                ShowQueryErrorDialog();

            return VSConstants.S_OK;
        }
 int IVsTrackProjectDocumentsEvents2.OnQueryAddFiles(
     IVsProject pProject,
     int cFiles,
     string[] rgpszMkDocuments,
     VSQUERYADDFILEFLAGS[] rgFlags,
     VSQUERYADDFILERESULTS[] pSummaryResult,
     VSQUERYADDFILERESULTS[] rgResults)
 {
     return VSConstants.S_OK;
 }
Esempio n. 19
0
        /// <summary>
        /// Determines if it is okay to add a collection of files (possibly from source control) whose final destination may be different from a source location.
        /// </summary>
        /// <param name="pProject">[in] Project making the request about adding files.</param>
        /// <param name="cFiles">[in] The number of files represented in the rgpszNewMkDocuments, rgpszSrcMkDocuments, rgFlags, and rgResults arrays.</param>
        /// <param name="rgpszNewMkDocuments">[in] An array of file names that indicate the files' final destination.</param>
        /// <param name="rgpszSrcMkDocuments">[in] An array of file names specifying the source location of the files.</param>
        /// <param name="rgFlags">[in] An array of values, one element for each file, from the <see cref="T:Microsoft.VisualStudio.Shell.Interop.VSQUERYADDFILEFLAGS"></see> enumeration.</param>
        /// <param name="pSummaryResult">[out] Returns an overall status for all files as a value from the <see cref="T:Microsoft.VisualStudio.Shell.Interop.VSQUERYADDFILERESULTS"></see> enumeration.</param>
        /// <param name="rgResults">[out] An array that is to be filled in with the status of each file. Each status is a value from the <see cref="T:Microsoft.VisualStudio.Shell.Interop.VSQUERYADDFILERESULTS"></see> enumeration.</param>
        /// <returns>
        /// If the method succeeds, it returns <see cref="F:Microsoft.VisualStudio.VSConstants.S_OK"></see>. If it fails, it returns an error code.
        /// </returns>
        /// <remarks>Deny a query only if allowing the operation would compromise your stable state</remarks>
        public int OnQueryAddFilesEx(IVsProject pProject, int cFiles, string[] rgpszNewMkDocuments, string[] rgpszSrcMkDocuments, VSQUERYADDFILEFLAGS[] rgFlags, VSQUERYADDFILERESULTS[] pSummaryResult, VSQUERYADDFILERESULTS[] rgResults)
        {
            // For now, we allow adding all files as is
            // We might propose moving files to within a managed root

            _collectHints = true; // Some projects call HandsOff(file) on which files they wish to import. Use that to get more information
            bool allOk = true;

            bool track = SccProvider.TrackProjectChanges(pProject as IVsSccProject2);

            for (int i = 0; i < cFiles; i++)
            {
                bool ok = true;

                if (string.IsNullOrEmpty(rgpszNewMkDocuments[i]) || !SccProvider.IsSafeSccPath(rgpszNewMkDocuments[i]))
                    continue;

                // Save the origins of the to be added files as they are not available in the added event

                string newDoc = SvnTools.GetNormalizedFullPath(rgpszNewMkDocuments[i]);
                string origDoc = rgpszSrcMkDocuments[i];

                if (origDoc != null && SccProvider.IsSafeSccPath(origDoc))
                    origDoc = SvnTools.GetNormalizedFullPath(origDoc);
                else
                    origDoc = null;

                if (!string.IsNullOrEmpty(newDoc) && !string.IsNullOrEmpty(origDoc)
                    && !string.Equals(newDoc, origDoc, StringComparison.OrdinalIgnoreCase)) // VS tries to add the file
                {
                    _fileOrigins[newDoc] = origDoc;
                }

                if (track && !SvnCanAddPath(newDoc, SvnNodeKind.File))
                    ok = false;

                if (rgResults != null)
                    rgResults[i] = ok ? VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK : VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;

                if (!ok)
                    allOk = false;
            }

            if (pSummaryResult != null)
                pSummaryResult[0] = allOk ? VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK : VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddNotOK;

            RegisterForSccCleanup(); // Clear the origins table after adding

            if (!allOk)
            {
                if (!_inBatch)
                    ShowQueryErrorDialog();
            }

            return VSConstants.S_OK;
        }