-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseCopyCommand.cs
157 lines (143 loc) · 6.03 KB
/
BaseCopyCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) mere-human. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace CopyRelativePath
{
internal class BaseCopyCommand
{
protected ExtensionPackage package;
/// <summary>
/// Returns relative path to the selected item.
/// </summary>
/// <returns>path string or null</returns>
protected string GetRelPath()
{
ThreadHelper.ThrowIfNotOnUIThread();
string fileName = "";
if (package.DTE.ActiveWindow.Type == vsWindowType.vsWindowTypeDocument)
{
// Document context menu.
var activeDoc = package.DTE.ActiveDocument;
if (activeDoc != null)
fileName = activeDoc.FullName;
}
if (string.IsNullOrEmpty(fileName) || package.DTE.ActiveWindow.Type == vsWindowType.vsWindowTypeSolutionExplorer)
{
// Solution explorer context menu.
fileName = GetPathFromSelectedProjectItem();
if (string.IsNullOrEmpty(fileName))
{
// Probably, selected item is not part of the project.
fileName = GetPathFromHierarchy();
}
}
// Do nothing if failed to obtain the correct file name.
if (string.IsNullOrEmpty(fileName) || !File.Exists(fileName))
return null;
string basePath = package.OptionBasePath;
if (string.IsNullOrEmpty(basePath) || !Path.IsPathRooted(basePath))
basePath = Path.GetDirectoryName(package.DTE.Solution.FullName);
// Compare path components ignoring case (assume NTFS).
if (fileName.StartsWith(basePath, StringComparison.CurrentCultureIgnoreCase))
{
fileName = fileName.Remove(0, basePath.Length);
}
else
{
// Trim common prefix
string[] basePathComponents = basePath.Split(Path.DirectorySeparatorChar);
string[] fileNameComponents = fileName.Split(Path.DirectorySeparatorChar);
int minLen = Math.Min(basePathComponents.Length, fileNameComponents.Length);
int i = 0;
for (; i < minLen; ++i)
{
if (!fileNameComponents[i].Equals(basePathComponents[i], StringComparison.CurrentCultureIgnoreCase))
break;
}
var subPathComponents = fileNameComponents.Skip(i).ToArray();
fileName = Path.Combine(subPathComponents);
}
fileName = fileName.TrimStart(Path.DirectorySeparatorChar);
if (package.OptionIsForwardSlash)
fileName = fileName.Replace(Path.DirectorySeparatorChar, '/');
return fileName;
}
protected string GetURLPath()
{
ThreadHelper.ThrowIfNotOnUIThread();
if (string.IsNullOrEmpty(package.OptionPrefix))
{
MessageBox.Show("URL prefix option is empty", "Copy URL", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return null;
}
else
{
string filePath = GetRelPath();
filePath = Path.Combine(package.OptionPrefix, filePath);
filePath = filePath.Replace(Path.DirectorySeparatorChar, '/');
return filePath;
}
}
private string GetPathFromSelectedProjectItem()
{
ThreadHelper.ThrowIfNotOnUIThread();
var selItems = package.DTE.SelectedItems;
if (selItems.Count > 0)
{
EnvDTE.SelectedItem item = selItems.Item(1); // 1-based index
if (item != null)
{
var projItem = item.ProjectItem;
if (projItem != null)
{
// Selected item is a part of the project.
if (projItem.FileCount > 0)
return projItem.FileNames[0];
}
}
}
return "";
}
private string GetPathFromHierarchy()
{
ThreadHelper.ThrowIfNotOnUIThread();
var slnExplorer = package.DTE.ToolWindows.SolutionExplorer;
if (slnExplorer.SelectedItems is object[] hierItems && hierItems.Length > 0)
{
// Get all the parent items up to the solution item (excluding it).
var hierPath = new List<string>();
var hierItem = hierItems[0] as EnvDTE.UIHierarchyItem;
if (hierItem != null && hierItem.IsSelected)
{
while (hierItem != null)
{
var parent = hierItem.Collection.Parent;
if (parent.Equals(slnExplorer) || parent is EnvDTE.Solution)
break;
hierPath.Insert(0, hierItem.Name);
hierItem = parent as EnvDTE.UIHierarchyItem;
}
}
if (hierPath.Count != 0)
{
string slnDir = Path.GetDirectoryName(package.DTE.Solution.FileName);
if (hierPath.Count > 1)
{
// Remove project item (which comes 1st) if there is no directory for it.
string filePath = Path.Combine(slnDir, hierPath[0]);
if (!Directory.Exists(filePath))
hierPath.RemoveAt(0);
}
return Path.Combine(slnDir, string.Join("\\", hierPath));
}
}
return "";
}
}
}