in Common/Product/SharedProject/ProjectNode.CopyPaste.cs [907:1104]
private Addition CanAddFileFromProjectReference(string projectRef, string targetFolder, bool fromFolder = false) {
Utilities.ArgumentNotNullOrEmpty("projectRef", projectRef);
IVsSolution solution = Project.GetService(typeof(IVsSolution)) as IVsSolution;
Utilities.CheckNotNull(solution);
uint itemidLoc;
IVsHierarchy hierarchy;
string str;
VSUPDATEPROJREFREASON[] reason = new VSUPDATEPROJREFREASON[1];
if (ErrorHandler.Failed(solution.GetItemOfProjref(projectRef, out hierarchy, out itemidLoc, out str, reason))) {
// the file may have been deleted between the copy & paste
string path;
Guid projectGuid;
GetPathAndProjectId(projectRef, out projectGuid, out path);
ReportMissingItem(path);
return null;
}
Utilities.CheckNotNull(hierarchy);
// This will throw invalid cast exception if the hierrachy is not a project.
IVsProject project = (IVsProject)hierarchy;
object isLinkValue;
bool isLink = false;
if (ErrorHandler.Succeeded(((IVsHierarchy)project).GetProperty(itemidLoc, (int)__VSHPROPID2.VSHPROPID_IsLinkFile, out isLinkValue))) {
if (isLinkValue is bool) {
isLink = (bool)isLinkValue;
}
}
string moniker;
ErrorHandler.ThrowOnFailure(project.GetMkDocument(itemidLoc, out moniker));
if (DropEffect == DropEffect.Move && IsBadMove(targetFolder, moniker, true)) {
return null;
}
if (!File.Exists(moniker)) {
Utilities.ShowMessageBox(
Project.Site,
String.Format("The item '{0}' does not exist in the project directory. It may have been moved, renamed or deleted.", Path.GetFileName(moniker)),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
// Check that the source and destination paths aren't the same since we can't move an item to itself.
// If they are in fact the same location, throw an error that copy/move will not work correctly.
if (DropEffect == DropEffect.Move && !CommonUtils.IsSamePath(Path.GetDirectoryName(moniker), Path.GetDirectoryName(targetFolder))) {
try {
string sourceLinkTarget = NativeMethods.GetAbsolutePathToDirectory(Path.GetDirectoryName(moniker));
string destinationLinkTarget = null;
// if the directory doesn't exist, just skip this. We will create it later.
if (Directory.Exists(targetFolder)) {
try {
destinationLinkTarget = NativeMethods.GetAbsolutePathToDirectory(targetFolder);
} catch (FileNotFoundException) {
// This can occur if the user had a symlink'd directory and deleted the backing directory.
Utilities.ShowMessageBox(
Project.Site,
String.Format(
"Unable to find the destination folder."),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
}
// If the paths are the same, we can't really move the file...
if (destinationLinkTarget != null && CommonUtils.IsSamePath(sourceLinkTarget, destinationLinkTarget)) {
CannotMoveSameLocation(moniker);
return null;
}
} catch (Exception e) {
if (e.IsCriticalException()) {
throw;
}
TaskDialog.ForException(Project.Site, e, String.Empty, Project.IssueTrackerUrl).ShowModal();
return null;
}
}
// Begin the move operation now that we are past pre-checks.
var existingChild = Project.FindNodeByFullPath(moniker);
if (isLink) {
// links we just want to update the link node for...
if (existingChild != null) {
if (Utilities.IsSameComObject(Project, project)) {
if (DropEffect != DropEffect.Move) {
Utilities.ShowMessageBox(
Project.Site,
String.Format("Cannot copy linked files within the same project. You cannot have more than one link to the same file in a project."),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
} else {
Utilities.ShowMessageBox(
Project.Site,
String.Format("There is already a link to '{0}'. You cannot have more than one link to the same file in a project.", moniker),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
}
return new ReparentLinkedFileAddition(Project, targetFolder, moniker);
}
string newPath = Path.Combine(targetFolder, Path.GetFileName(moniker));
if (File.Exists(newPath) &&
CommonUtils.IsSamePath(
NativeMethods.GetAbsolutePathToDirectory(newPath),
NativeMethods.GetAbsolutePathToDirectory(moniker))) {
newPath = GetCopyName(newPath);
}
bool ok = false;
if (DropEffect == DropEffect.Move && Utilities.IsSameComObject(project, Project)) {
if (existingChild != null && existingChild.ItemNode != null && existingChild.ItemNode.IsExcluded) {
// https://nodejstools.codeplex.com/workitem/271
// The item is excluded, so we don't need to ask if we can rename it.
ok = true;
} else {
ok = Project.Tracker.CanRenameItem(moniker, newPath, VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags);
}
} else {
ok = Project.Tracker.CanAddItems(
new[] { newPath },
new VSQUERYADDFILEFLAGS[] { VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags });
}
if (ok) {
if (File.Exists(newPath)) {
if (DropEffect == DropEffect.Move &&
Utilities.IsSameComObject(project, Project) &&
Project.FindNodeByFullPath(newPath) != null) {
// if we're overwriting an item, we're moving it, make sure that's ok.
// OverwriteFileAddition will handle the remove from the hierarchy
if (!Project.Tracker.CanRemoveItems(new[] { newPath }, new[] { VSQUERYREMOVEFILEFLAGS.VSQUERYREMOVEFILEFLAGS_NoFlags })) {
return null;
}
}
bool? overwrite = OverwriteAllItems;
if (overwrite == null) {
OverwriteFileDialog dialog;
if (!PromptOverwriteFile(moniker, out dialog)) {
return null;
}
overwrite = dialog.ShouldOverwrite;
if (dialog.AllItems) {
OverwriteAllItems = overwrite;
}
}
if (overwrite.Value) {
return new OverwriteFileAddition(Project, targetFolder, DropEffect, moniker, Path.GetFileName(newPath), project);
} else {
return SkipOverwriteAddition.Instance;
}
} else if (Directory.Exists(newPath)) {
Utilities.ShowMessageBox(
Project.Site,
SR.GetString(SR.DirectoryExists, CommonUtils.GetFileOrDirectoryName(newPath)),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
if (newPath.Length >= NativeMethods.MAX_PATH) {
Utilities.ShowMessageBox(
Project.Site,
SR.GetString(SR.PathTooLongShortMessage),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
return new FileAddition(Project, targetFolder, DropEffect, moniker, Path.GetFileName(newPath), project);
}
return null;
}