-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainWindow.xaml.cs
More file actions
208 lines (173 loc) · 6.42 KB
/
Copy pathMainWindow.xaml.cs
File metadata and controls
208 lines (173 loc) · 6.42 KB
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using CloudIgnore.Models;
using CloudIgnore.Services;
using Microsoft.Win32;
namespace CloudIgnore;
public partial class MainWindow : Window
{
private readonly DropboxIgnoreService _ignoreService = new();
private readonly GitignoreParser _gitignoreParser = new();
private readonly ObservableCollection<IgnoreProfile> _profiles = new();
private readonly ObservableCollection<ScanMatch> _results = new();
private readonly DropboxLocator _dropboxLocator = new();
private readonly AppSettings _settings = AppSettings.Load();
// No default root. On startup the app tries the folder used last time, then
// auto-detects Dropbox, and only asks the user if neither works out.
private string _rootPath = string.Empty;
private IgnoreProfile _activeProfile;
public MainWindow()
{
InitializeComponent();
_profiles.Add(IgnoreProfile.DotNetBuildFolders());
_profiles.Add(IgnoreProfile.WebNodeFolders());
_activeProfile = _profiles[0];
ProfileList.ItemsSource = _profiles;
ProfileList.SelectedIndex = 0;
ResultsGrid.ItemsSource = _results;
ShowRootPath();
UpdateStats();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 1. The folder chosen last time, if it's still there.
if (!string.IsNullOrWhiteSpace(_settings.RootPath) && Directory.Exists(_settings.RootPath))
{
SetRoot(_settings.RootPath, "Remembered from your last session.", save: false);
return;
}
// 2. Dropbox's own settings, or a folder that carries its marker files.
var detected = _dropboxLocator.FindRoots();
if (detected.Count > 0)
{
var note = detected.Count == 1
? "Found your Dropbox folder automatically."
: $"Found {detected.Count} Dropbox folders — using the first. Use Browse Root to switch.";
SetRoot(detected[0], note);
return;
}
// 3. Nothing found, so ask before the window is usable.
PromptForRoot(
"Choose your Dropbox folder",
"CloudIgnore couldn't find your Dropbox folder. Please choose it so scans start in the right place.");
}
private void PromptForRoot(string title, string? explanation = null)
{
if (explanation is not null)
{
MessageBox.Show(explanation, "Choose a folder", MessageBoxButton.OK, MessageBoxImage.Information);
}
var dialog = new OpenFolderDialog
{
Title = title,
InitialDirectory = DialogStartFolder
};
if (dialog.ShowDialog() == true)
SetRoot(dialog.FolderName, "Chosen by you. CloudIgnore will remember it next time.");
}
// One place to change the root so the label, the saved setting, and the
// scan all stay in step.
private void SetRoot(string path, string note, bool save = true)
{
_rootPath = path;
RootSourceText.Text = note;
ShowRootPath();
if (save)
{
_settings.RootPath = path;
_settings.Save();
}
}
private void ShowRootPath()
{
RootPathText.Text = string.IsNullOrWhiteSpace(_rootPath)
? "No folder selected — choose one with Browse Root"
: _rootPath;
}
// The folder picker needs somewhere to start. Before a root is chosen,
// fall back to the user's profile folder rather than a hardcoded path.
private string DialogStartFolder =>
string.IsNullOrWhiteSpace(_rootPath)
? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
: _rootPath;
private void BrowseRoot_Click(object sender, RoutedEventArgs e)
{
PromptForRoot("Choose a root folder to scan");
}
private void ImportGitignore_Click(object sender, RoutedEventArgs e)
{
var dialog = new OpenFileDialog
{
Title = "Select a .gitignore file",
Filter = ".gitignore|.gitignore|All files|*.*",
FileName = ".gitignore",
InitialDirectory = DialogStartFolder
};
if (dialog.ShowDialog() != true)
return;
var profile = _gitignoreParser.Parse(dialog.FileName);
_profiles.Add(profile);
ProfileList.SelectedItem = profile;
}
private void ProfileList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (ProfileList.SelectedItem is IgnoreProfile profile)
{
_activeProfile = profile;
ActiveProfileText.Text = profile.Name;
RuleCountText.Text = $"{profile.Rules.Count} active";
}
}
private void ScanNow_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(_rootPath) || !Directory.Exists(_rootPath))
{
MessageBox.Show(
"Choose a folder to scan first using Browse Root.",
"No folder selected",
MessageBoxButton.OK,
MessageBoxImage.Information);
return;
}
_results.Clear();
var matches = _ignoreService.Scan(_rootPath, _activeProfile);
foreach (var match in matches)
_results.Add(match);
UpdateStats();
}
private void ApplyIgnore_Click(object sender, RoutedEventArgs e)
{
foreach (var match in _results)
{
if (!match.Selected || match.Status == MatchStatus.AlreadyIgnored)
continue;
_ignoreService.Apply(match);
}
ResultsGrid.Items.Refresh();
UpdateStats();
}
private void UndoIgnore_Click(object sender, RoutedEventArgs e)
{
foreach (var match in _results)
{
if (!match.Selected)
continue;
_ignoreService.Undo(match);
}
ResultsGrid.Items.Refresh();
UpdateStats();
}
private void ClearResults_Click(object sender, RoutedEventArgs e)
{
_results.Clear();
UpdateStats();
}
private void UpdateStats()
{
ActiveProfileText.Text = _activeProfile.Name;
RuleCountText.Text = $"{_activeProfile.Rules.Count} active";
MatchesFoundText.Text = _results.Count.ToString();
ReadyToApplyText.Text = _results.Count(m => m.Status == MatchStatus.Pending).ToString();
}
}