-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathUserControlRemoteEdit.cs
266 lines (234 loc) · 10.4 KB
/
UserControlRemoteEdit.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
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace GitForce
{
public partial class RemoteEdit : UserControl
{
/// <summary>
/// Current parsing information of the URL strings
/// </summary>
private ClassUrl.Url _fetchUrl;
private ClassUrl.Url _pushUrl;
/// <summary>
/// Flag that we are in editing mode
/// </summary>
private bool _isEditing = false;
/// <summary>
/// Context menus used by the convenience buttons that list all existing fetch and push URLs
/// </summary>
private readonly ContextMenuStrip _menuFetch = new ContextMenuStrip();
private readonly ContextMenuStrip _menuPush = new ContextMenuStrip();
/// <summary>
/// Callback delegate to signal when a text in a name or URL
/// fields have changed.
/// </summary>
public delegate void AnyTextChangedDelegate(bool valid);
public AnyTextChangedDelegate AnyTextChanged = VoidAnyTextChanged;
private static void VoidAnyTextChanged(bool valid) { }
public RemoteEdit()
{
InitializeComponent();
// Add button click handlers that will expand the list of existing fetch and push URLs
_menuFetch.ItemClicked += MenuFetchItemClicked;
_menuPush.ItemClicked += MenuPushItemClicked;
}
/// <summary>
/// Enable or disable input fields.
/// </summary>
/// <param name="name">Enable or disable name input field</param>
/// <param name="all">Enable or disable all other fields except the name</param>
public void Enable(bool name, bool all)
{
_isEditing = all; // When all fields are enabled, we are in editing mode
textName.ReadOnly = !name;
textUrlPush.ReadOnly = textUrlFetch.ReadOnly = textPushCmd.ReadOnly = !all;
btListFetch.Enabled = btListPush.Enabled = textPassword.Enabled = btHttps.Enabled = all;
SomeTextChanged(null, null);
}
/// <summary>
/// Clear all input fields
/// </summary>
public void Clear()
{
textName.Text = "";
textUrlFetch.Text = "";
textUrlPush.Text = "";
textPushCmd.Text = "";
textPassword.Text = "";
btWWW1.Enabled = false;
btWWW2.Enabled = false;
btListFetch.Enabled = btListPush.Enabled = btHttps.Enabled = false;
textPassword.ReadOnly = true;
}
/// <summary>
/// Set all input fields to parameter values
/// </summary>
/// <param name="repo">Values to set</param>
public void Set(ClassRemotes.Remote repo)
{
textName.Text = repo.Name;
textUrlFetch.Text = repo.UrlFetch;
textUrlPush.Text = repo.UrlPush;
textPushCmd.Text = repo.PushCmd;
btWWW1.Enabled = isValidUrl(textUrlFetch.Text);
btWWW2.Enabled = isValidUrl(textUrlPush.Text);
textPassword.Text = repo.Password;
// Rebuild the state variables _after_ all the URLs have been inserted
SomeTextChanged(null, null);
}
/// <summary>
/// Return current values from the input fields
/// </summary>
/// <returns>Structure with values</returns>
public ClassRemotes.Remote Get()
{
ClassRemotes.Remote repo = new ClassRemotes.Remote();
repo.Name = textName.Text.Trim();
repo.PushCmd = textPushCmd.Text.Trim();
repo.Password = textPassword.Text.Trim();
// For SSH, make sure the URL string follows the strict format
if (_fetchUrl.Type == ClassUrl.UrlType.Ssh)
repo.UrlFetch = ClassUrl.ToCanonical(textUrlFetch.Text.Trim());
else
repo.UrlFetch = textUrlFetch.Text.Trim();
if (_pushUrl.Type == ClassUrl.UrlType.Ssh)
repo.UrlPush = ClassUrl.ToCanonical(textUrlPush.Text.Trim());
else
repo.UrlPush = textUrlPush.Text.Trim();
return repo;
}
/// <summary>
/// Validate entries and return true if they are reasonably valid
/// </summary>
public bool IsValid()
{
_fetchUrl = ClassUrl.Parse(textUrlFetch.Text.Trim());
_pushUrl = ClassUrl.Parse(textUrlPush.Text.Trim());
// Consider valid entry if the name is ok and some combination of urls
return textName.Text.Trim().Length > 0 && _fetchUrl.Type != ClassUrl.UrlType.Unknown;
}
/// <summary>
/// This function is called when text boxes name and URL changed.
/// It calls delegate back to the caller.
/// </summary>
private void SomeTextChanged(object sender, EventArgs e)
{
// Remove "git clone" substring from the input text which is commonly pasted from an online repo command
if (textUrlFetch.Text.Trim().StartsWith("git clone"))
textUrlFetch.Text = textUrlFetch.Text.Replace("git clone", "").Trim();
if (textUrlPush.Text.Trim().StartsWith("git clone"))
textUrlPush.Text = textUrlPush.Text.Replace("git clone", "").Trim();
// Call the delegate and also reparse our fetch and push URLs
AnyTextChanged(IsValid());
// Change enable properties only if we are in editing mode, otherwise controls are grayed out
if (_isEditing)
{
// Enable SSH button if one of the URLs uses SSH connection but only on Windows OS
btSsh.Enabled = !ClassUtils.IsMono() &
((_fetchUrl.Type == ClassUrl.UrlType.Ssh) || (_pushUrl.Type == ClassUrl.UrlType.Ssh));
// Enable HTTPS password edit, reveal and manage buttons if one of the URLs use HTTPS connection
btHttps.Enabled = (_fetchUrl.Type == ClassUrl.UrlType.Https) || (_pushUrl.Type == ClassUrl.UrlType.Https);
checkReveal.Enabled = btHttps.Enabled;
textPassword.ReadOnly = !btHttps.Enabled;
btWWW1.Enabled = _fetchUrl.Ok;
btWWW2.Enabled = _pushUrl.Ok;
}
}
/// <summary>
/// Manage SSH keys
/// </summary>
private void BtSshClick(object sender, EventArgs e)
{
FormSSH formSsh = new FormSSH();
// Add one of the URLs from our input into the text box of a URL to add
if (_fetchUrl.Type == ClassUrl.UrlType.Ssh)
formSsh.AddHost(textUrlFetch.Text.Trim());
else
if (_pushUrl.Type == ClassUrl.UrlType.Ssh)
formSsh.AddHost(textUrlPush.Text.Trim());
// Show the dialog. A previous call to AddHost will set the "Remote Keys" tab as current,
// with one of the host strings (URLs) added into the input text box, ready to click on Add Host.
formSsh.ShowDialog();
}
/// <summary>
/// User clicked on the "web" button to the left of the git repo address.
/// Find the canonical web site and open it
/// </summary>
private void BtWwwClick(object sender, EventArgs e)
{
string key = ((Button) sender).Tag.ToString();
ClassUrl.Url url = key == "Fetch" ? _fetchUrl : _pushUrl;
// Find a generic host name
string target = "http://" + url.Host;
// Detect some special hosts for which we can form a complete path
if (url.Host.Contains("github"))
target += "/" + url.Path;
if (url.Host.Contains(".code.sf.net"))
target = "https://sourceforge.net/projects/" + url.Name;
ClassUtils.OpenWebLink(target);
}
/// <summary>
/// Checks the given web target link and returns true if it is reasonably valid URL
/// </summary>
private bool isValidUrl(string target)
{
ClassUrl.Url url = ClassUrl.Parse(target.Trim());
return url.Ok;
}
/// <summary>
/// User clicked on the fetch help button, open a context dialog to select from the existing URLs
/// </summary>
private void BtFetchClicked(object sender, EventArgs e)
{
_menuFetch.Items.Clear();
// Pick up a list of existing remote URLs and show them in the pull-down list
List<string> hintUrls = App.Repos.GetRemoteUrls();
foreach (var hintUrl in hintUrls)
_menuFetch.Items.Add(hintUrl);
_menuFetch.Show(btListFetch, new Point(0, btListFetch.Height));
}
/// <summary>
/// User clicked on the push help button, open a context dialog to select from the existing URLs
/// </summary>
private void BtPushClicked(object sender, EventArgs e)
{
_menuPush.Items.Clear();
// Pick up a list of existing remote URLs and show them in the pull-down list
List<string> hintUrls = App.Repos.GetRemoteUrls();
foreach (var hintUrl in hintUrls)
_menuPush.Items.Add(hintUrl);
_menuPush.Show(btListPush, new Point(0, btListPush.Height));
}
/// <summary>
/// Item menu handler for the fetch help button
/// </summary>
void MenuFetchItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
textUrlFetch.Text = e.ClickedItem.Text;
}
/// <summary>
/// Item menu handler for the push help button
/// </summary>
void MenuPushItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
textUrlPush.Text = e.ClickedItem.Text;
}
/// <summary>
/// Checked state of reveal button changed, show or hide password
/// </summary>
private void CheckRevealCheckedChanged(object sender, EventArgs e)
{
textPassword.UseSystemPasswordChar = !checkReveal.Checked;
}
/// <summary>
/// User clicked on the HTTPS authentication button, open a dialog to enter HTTPS credentials
/// </summary>
private void BtHttpsClicked(object sender, EventArgs e)
{
FormHttps formHttps = new FormHttps();
formHttps.ShowDialog();
}
}
}