Skip to content

Commit 65044d1

Browse files
committed
1 parent b753321 commit 65044d1

File tree

9 files changed

+175
-130
lines changed

9 files changed

+175
-130
lines changed

TSVN/Helpers/CommandHelper.cs

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,71 @@
11
using EnvDTE;
2-
using Microsoft.Win32;
32
using System;
4-
using System.IO;
5-
using System.Linq;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
65
using System.Windows.Forms;
6+
using SamirBoulema.TSVN.Properties;
77
using Process = System.Diagnostics.Process;
88

99
namespace SamirBoulema.TSVN.Helpers
1010
{
1111
public class CommandHelper
1212
{
13-
private DTE dte;
14-
private string tortoiseProc;
15-
13+
private readonly DTE _dte;
14+
private readonly string _tortoiseProc;
15+
private readonly FileHelper _fileHelper;
1616

1717
public CommandHelper(DTE dte)
1818
{
19-
this.dte = dte;
20-
tortoiseProc = GetTortoiseSVNProc();
19+
_dte = dte;
20+
_tortoiseProc = FileHelper.GetTortoiseSvnProc();
21+
_fileHelper = new FileHelper(dte);
2122
}
2223

2324
public void Commit()
2425
{
25-
dte.ExecuteCommand("File.SaveAll", string.Empty);
26-
Commit(GetSolutionDir());
26+
_dte.ExecuteCommand("File.SaveAll", string.Empty);
27+
Commit(_fileHelper.GetSolutionDir());
2728
}
2829

2930
public void Commit(string filePath)
3031
{
3132
if (string.IsNullOrEmpty(filePath)) return;
32-
StartProcess(tortoiseProc, string.Format("/command:commit /path:\"{0}\" /closeonend:0", filePath));
33+
StartProcess(_tortoiseProc, $"/command:commit /path:\"{filePath}\" /closeonend:0");
3334
}
3435

3536
public void Revert()
3637
{
37-
Revert(GetSolutionDir());
38+
Revert(_fileHelper.GetSolutionDir());
3839
}
3940

4041
public void Revert(string filePath)
4142
{
4243
if (string.IsNullOrEmpty(filePath)) return;
43-
StartProcess(tortoiseProc, string.Format("/command:revert /path:\"{0}\" /closeonend:0", filePath));
44-
}
45-
46-
private string GetSolutionDir()
47-
{
48-
string fileName = dte.Solution.FullName;
49-
if (string.IsNullOrEmpty(fileName))
50-
{
51-
MessageBox.Show("Please open a solution first", "TSVN error", MessageBoxButtons.OK, MessageBoxIcon.Error);
52-
}
53-
else
54-
{
55-
var path = Path.GetDirectoryName(fileName);
56-
return FindSvndir(path);
57-
}
58-
return string.Empty;
44+
StartProcess(_tortoiseProc, $"/command:revert /path:\"{filePath}\" /closeonend:0");
5945
}
6046

61-
private static string FindSvndir(string path)
47+
public List<string> GetPendingChanges()
6248
{
63-
try
49+
var pendingChanges = new List<string>();
50+
var proc = new Process
6451
{
65-
var di = new DirectoryInfo(path);
66-
if (di.GetDirectories().Any(d => d.Name.Equals(".svn")))
67-
{
68-
return di.FullName;
69-
}
70-
if (di.Parent != null)
52+
StartInfo = new ProcessStartInfo
7153
{
72-
return FindSvndir(di.Parent.FullName);
54+
FileName = "cmd.exe",
55+
Arguments = $"/c cd /D \"{_fileHelper.GetSolutionDir()}\" && \"{FileHelper.GetSvnExec()}\" status" + (Settings.Default.HideUnversioned ? " -q" : string.Empty),
56+
UseShellExecute = false,
57+
RedirectStandardOutput = true,
58+
RedirectStandardError = true,
59+
CreateNoWindow = true
7360
}
74-
throw new FileNotFoundException("Unable to find .svn directory.\nIs your solution under SVN source control?");
75-
}
76-
catch (Exception e)
61+
};
62+
proc.Start();
63+
while (!proc.StandardOutput.EndOfStream)
7764
{
78-
MessageBox.Show(e.Message, "TSVN error", MessageBoxButtons.OK, MessageBoxIcon.Error);
65+
pendingChanges.Add(proc.StandardOutput.ReadLine());
7966
}
80-
return string.Empty;
81-
}
8267

83-
private string GetTortoiseSVNProc()
84-
{
85-
return (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseSVN", "ProcPath", @"C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe");
68+
return pendingChanges;
8669
}
8770

8871
private static void StartProcess(string application, string args)

TSVN/Helpers/FileHelper.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,31 @@ namespace SamirBoulema.TSVN.Helpers
99
{
1010
public class FileHelper
1111
{
12-
private DTE dte;
12+
private readonly DTE _dte;
1313

1414
public FileHelper(DTE dte)
1515
{
16-
this.dte = dte;
16+
_dte = dte;
1717
}
1818

19-
public string GetTortoiseSVNProc()
19+
public static string GetTortoiseSvnProc()
2020
{
2121
return (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseSVN", "ProcPath", @"C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe");
2222
}
2323

24-
public string GetSVNExec()
24+
public static string GetSvnExec()
2525
{
26-
return GetTortoiseSVNProc().Replace("TortoiseProc.exe", "svn.exe");
26+
return GetTortoiseSvnProc().Replace("TortoiseProc.exe", "svn.exe");
2727
}
2828

2929
public void SaveAllFiles()
3030
{
31-
dte.ExecuteCommand("File.SaveAll");
31+
_dte.ExecuteCommand("File.SaveAll");
3232
}
3333

3434
public string GetSolutionDir()
3535
{
36-
string fileName = dte.Solution.FullName;
36+
var fileName = _dte.Solution.FullName;
3737
if (!string.IsNullOrEmpty(fileName))
3838
{
3939
var path = Path.GetDirectoryName(fileName);

TSVN/Properties/Settings.Designer.cs

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TSVN/Properties/Settings.settings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version='1.0' encoding='utf-8'?>
2+
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SamirBoulema.TSVN.Properties" GeneratedClassName="Settings">
3+
<Profiles />
4+
<Settings>
5+
<Setting Name="HideUnversioned" Type="System.Boolean" Scope="User">
6+
<Value Profile="(Default)">False</Value>
7+
</Setting>
8+
</Settings>
9+
</SettingsFile>

TSVN/TSVN.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@
179179
<Compile Include="Helpers\CommandHelper.cs" />
180180
<Compile Include="Helpers\FileHelper.cs" />
181181
<Compile Include="Models\TSVNTreeViewItem.cs" />
182+
<Compile Include="Properties\Settings.Designer.cs">
183+
<AutoGen>True</AutoGen>
184+
<DesignTimeSharedInput>True</DesignTimeSharedInput>
185+
<DependentUpon>Settings.settings</DependentUpon>
186+
</Compile>
182187
<Compile Include="Resources.Designer.cs">
183188
<AutoGen>True</AutoGen>
184189
<DesignTime>True</DesignTime>
@@ -210,6 +215,10 @@
210215
<None Include="packages.config">
211216
<SubType>Designer</SubType>
212217
</None>
218+
<None Include="Properties\Settings.settings">
219+
<Generator>SettingsSingleFileGenerator</Generator>
220+
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
221+
</None>
213222
<None Include="source.extension.vsixmanifest">
214223
<SubType>Designer</SubType>
215224
</None>

TSVN/TSVNToolWindow.cs

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,20 @@
1-
namespace SamirBoulema.TSVN
1+
using SamirBoulema.TSVN.Properties;
2+
3+
namespace SamirBoulema.TSVN
24
{
3-
using System;
45
using System.Runtime.InteropServices;
56
using Microsoft.VisualStudio.Shell;
6-
using System.Diagnostics;
7-
using System.Collections.Generic;
87
using EnvDTE;
98
using Helpers;
10-
using Process = System.Diagnostics.Process;
119

12-
/// <summary>
13-
/// This class implements the tool window exposed by this package and hosts a user control.
14-
/// </summary>
15-
/// <remarks>
16-
/// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane,
17-
/// usually implemented by the package implementer.
18-
/// <para>
19-
/// This class derives from the ToolWindowPane class provided from the MPF in order to use its
20-
/// implementation of the IVsUIElementPane interface.
21-
/// </para>
22-
/// </remarks>
2310
[Guid("81a57ae8-6550-4dd0-940c-503d379550cc")]
2411
public class TSVNToolWindow : ToolWindowPane
2512
{
26-
private FileHelper fileHelper;
27-
private DocumentEvents documentEvents;
28-
private SolutionEvents solutionEvents;
29-
private TSVNToolWindowControl tsvnToolWindowControl;
13+
private FileHelper _fileHelper;
14+
private DocumentEvents _documentEvents;
15+
private SolutionEvents _solutionEvents;
16+
private readonly TSVNToolWindowControl _tsvnToolWindowControl;
17+
private CommandHelper _commandHelper;
3018

3119
/// <summary>
3220
/// Initializes a new instance of the <see cref="TSVNToolWindow"/> class.
@@ -37,58 +25,36 @@ public TSVNToolWindow() : base(null)
3725
Caption = "TSVN Pending Changes";
3826
Content = new TSVNToolWindowControl();
3927

40-
tsvnToolWindowControl = Content as TSVNToolWindowControl;
28+
_tsvnToolWindowControl = Content as TSVNToolWindowControl;
4129
}
4230

4331
public override void OnToolWindowCreated()
4432
{
4533
var tsvnPackage = Package as TSVNPackage;
46-
DTE dte = (DTE)tsvnPackage.GetServiceHelper(typeof(DTE));
47-
tsvnToolWindowControl.SetDTE(dte);
48-
fileHelper = new FileHelper(dte);
34+
var dte = (DTE)tsvnPackage.GetServiceHelper(typeof(DTE));
35+
_tsvnToolWindowControl.SetDTE(dte);
36+
_fileHelper = new FileHelper(dte);
37+
_commandHelper = new CommandHelper(dte);
4938

50-
documentEvents = dte.Events.DocumentEvents;
51-
documentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
39+
_documentEvents = dte.Events.DocumentEvents;
40+
_documentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
5241

53-
solutionEvents = dte.Events.SolutionEvents;
54-
solutionEvents.Opened += SolutionEvents_Opened;
42+
_solutionEvents = dte.Events.SolutionEvents;
43+
_solutionEvents.Opened += SolutionEvents_Opened;
5544

56-
tsvnToolWindowControl.Update(GetPendingChanges(), fileHelper.GetSolutionDir());
57-
}
45+
_tsvnToolWindowControl.HideUnversionedButton.IsChecked = Settings.Default.HideUnversioned;
5846

59-
private void SolutionEvents_Opened()
60-
{
61-
tsvnToolWindowControl.Update(GetPendingChanges(), fileHelper.GetSolutionDir());
47+
_tsvnToolWindowControl.Update(_commandHelper.GetPendingChanges(), _fileHelper.GetSolutionDir());
6248
}
6349

64-
private void DocumentEvents_DocumentSaved(Document Document)
50+
private void SolutionEvents_Opened()
6551
{
66-
tsvnToolWindowControl.Update(GetPendingChanges(), fileHelper.GetSolutionDir());
52+
_tsvnToolWindowControl.Update(_commandHelper.GetPendingChanges(), _fileHelper.GetSolutionDir());
6753
}
6854

69-
private List<string> GetPendingChanges()
55+
private void DocumentEvents_DocumentSaved(Document document)
7056
{
71-
var pendingChanges = new List<string>();
72-
string output = string.Empty;
73-
var proc = new Process
74-
{
75-
StartInfo = new ProcessStartInfo
76-
{
77-
FileName = "cmd.exe",
78-
Arguments = $"/c cd /D \"{fileHelper.GetSolutionDir()}\" && \"{fileHelper.GetSVNExec()}\" status",
79-
UseShellExecute = false,
80-
RedirectStandardOutput = true,
81-
RedirectStandardError = true,
82-
CreateNoWindow = true
83-
}
84-
};
85-
proc.Start();
86-
while (!proc.StandardOutput.EndOfStream)
87-
{
88-
pendingChanges.Add(proc.StandardOutput.ReadLine());
89-
}
90-
91-
return pendingChanges;
57+
_tsvnToolWindowControl.Update(_commandHelper.GetPendingChanges(), _fileHelper.GetSolutionDir());
9258
}
9359
}
9460
}

TSVN/TSVNToolWindowControl.xaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<ControlTemplate.Triggers>
2222
<Trigger Property="IsMouseOver" Value="True">
2323
<Setter Property="Foreground" Value="Blue" />
24-
<Setter Property="Cursor" Value="Hand" />
2524
<!-- If we don't tell the background to change on hover, it will remain the same -->
2625
</Trigger>
2726
</ControlTemplate.Triggers>
@@ -164,11 +163,20 @@
164163
<ImageBrush ImageSource="Resources/octicons.png" ViewboxUnits="Absolute" Viewbox="192,0,16,16"/>
165164
</Button.OpacityMask>
166165
</Button>
167-
<Button x:Name="revertButton" ToolTip="Revert" Click="revertButton_Click" Width="16" BorderThickness="0">
166+
<Button x:Name="revertButton" ToolTip="Revert" Click="revertButton_Click" Width="16" Margin="0,0,5,0" BorderThickness="0">
168167
<Button.OpacityMask>
169168
<ImageBrush ImageSource="Resources/octicons.png" ViewboxUnits="Absolute" Viewbox="64,0,16,16"/>
170169
</Button.OpacityMask>
171170
</Button>
171+
<Border x:Name="HideUnversionedButtonBorder" BorderThickness="1" BorderBrush="Gray" Height="17">
172+
<ToggleButton x:Name="HideUnversionedButton" ToolTip="Hide unversioned files and folders"
173+
Checked="HideUnversionedButton_OnChecked" Unchecked="HideUnversionedButton_OnUnchecked" Height="16" Width="16" BorderThickness="0" Background="Black">
174+
<ToggleButton.OpacityMask>
175+
<ImageBrush ImageSource="Resources/octicons.png" ViewboxUnits="Absolute" Viewbox="112,0,16,16"/>
176+
</ToggleButton.OpacityMask>
177+
</ToggleButton>
178+
</Border>
179+
172180
</StackPanel>
173181
<TreeView Grid.Row="1" x:Name="treeView" Background="{x:Null}" BorderThickness="0,1,0,0" />
174182
</Grid>

0 commit comments

Comments
 (0)