PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/GitUI/FormPush.cs

https://github.com/eisnerd/gitextensions
C# | 650 lines | 530 code | 101 blank | 19 comment | 110 complexity | 09ab0c95aaf041e6e7c067bea3ca6494 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text.RegularExpressions;
  7. using System.Windows.Forms;
  8. using GitCommands;
  9. using GitCommands.Repository;
  10. using ResourceManager.Translation;
  11. using GitUI.RepoHosting;
  12. using GitUI.Script;
  13. namespace GitUI
  14. {
  15. public partial class FormPush : GitExtensionsForm
  16. {
  17. private const string PuttyText = "PuTTY";
  18. private const string HeadText = "HEAD";
  19. private readonly string _currentBranch;
  20. private readonly string _currentBranchRemote;
  21. private bool candidateForRebasingMergeCommit;
  22. private string selectedBranch;
  23. private string selectedBranchRemote;
  24. private string selectedRemoteBranchName;
  25. #region Translation
  26. private readonly TranslationString _branchNewForRemote =
  27. new TranslationString("The branch you are about to push seems to be a new branch for the remote." +
  28. Environment.NewLine + "Are you sure you want to push this branch?");
  29. private readonly TranslationString _cannotLoadPutty =
  30. new TranslationString("Cannot load SSH key. PuTTY is not configured properly.");
  31. private readonly TranslationString _pushCaption = new TranslationString("Push");
  32. private readonly TranslationString _pushToCaption = new TranslationString("Push to {0}");
  33. private readonly TranslationString _selectDestinationDirectory =
  34. new TranslationString("Please select a destination directory");
  35. private readonly TranslationString _selectRemote = new TranslationString("Please select a remote repository");
  36. private readonly TranslationString _selectTag =
  37. new TranslationString("You need to select a tag to push or select \"Push all tags\".");
  38. private readonly TranslationString _yes = new TranslationString("Yes");
  39. private readonly TranslationString _no = new TranslationString("No");
  40. #endregion
  41. public FormPush()
  42. {
  43. InitializeComponent();
  44. Translate();
  45. //can't be set in OnLoad, because after PushAndShowDialogWhenFailed()
  46. //they are reset to false
  47. PushAllTags.Checked = Settings.PushAllTags;
  48. AutoPullOnRejected.Checked = Settings.AutoPullOnRejected;
  49. if (GitCommandHelpers.VersionInUse.SupportPushWithRecursiveSubmodulesCheck)
  50. {
  51. RecursiveSubmodulesCheck.Enabled = true;
  52. RecursiveSubmodulesCheck.Checked = Settings.RecursiveSubmodulesCheck;
  53. }
  54. else
  55. {
  56. RecursiveSubmodulesCheck.Enabled = false;
  57. RecursiveSubmodulesCheck.Checked = false;
  58. }
  59. _currentBranch = Settings.Module.GetSelectedBranch();
  60. _NO_TRANSLATE_Remotes.DataSource = Settings.Module.GetRemotes();
  61. UpdateBranchDropDown();
  62. UpdateRemoteBranchDropDown();
  63. Push.Focus();
  64. _currentBranchRemote = Settings.Module.GetSetting(string.Format("branch.{0}.remote", _currentBranch));
  65. if (_currentBranchRemote.IsNullOrEmpty() && _NO_TRANSLATE_Remotes.Items.Count >= 2)
  66. {
  67. IList<string> remotes = (IList<string>)_NO_TRANSLATE_Remotes.DataSource;
  68. int i = remotes.IndexOf("origin");
  69. _NO_TRANSLATE_Remotes.SelectedIndex = i >= 0 ? i : 0;
  70. }
  71. else
  72. _NO_TRANSLATE_Remotes.Text = _currentBranchRemote;
  73. RemotesUpdated(null, null);
  74. }
  75. public void PushAndShowDialogWhenFailed(IWin32Window owner)
  76. {
  77. if (!PushChanges(owner))
  78. ShowDialog(owner);
  79. }
  80. public void PushAndShowDialogWhenFailed()
  81. {
  82. PushAndShowDialogWhenFailed(null);
  83. }
  84. private void BrowseSourceClick(object sender, EventArgs e)
  85. {
  86. var dialog = new FolderBrowserDialog { SelectedPath = PushDestination.Text };
  87. if (dialog.ShowDialog(this) == DialogResult.OK)
  88. PushDestination.Text = dialog.SelectedPath;
  89. }
  90. private void PushClick(object sender, EventArgs e)
  91. {
  92. if (PushChanges(this))
  93. Close();
  94. }
  95. private string GetDefaultPushLocal(String remote)
  96. {
  97. string localRef = null;
  98. //Get default push for this remote (if any). Local branch name is left of ":"
  99. var pushSettingValue = Settings.Module.GetSetting(string.Format("remote.{0}.push", remote));
  100. if (!string.IsNullOrEmpty(pushSettingValue))
  101. {
  102. var values = pushSettingValue.Split(':');
  103. if (values.Length > 0)
  104. localRef = values[0];
  105. }
  106. return localRef;
  107. }
  108. private string GetDefaultPushRemote(String remote)
  109. {
  110. string remoteRef = null;
  111. //Get default push for this remote (if any). Remote branch name is right of ":"
  112. var pushSettingValue = Settings.Module.GetSetting(string.Format("remote.{0}.push", remote));
  113. if (!string.IsNullOrEmpty(pushSettingValue))
  114. {
  115. var values = pushSettingValue.Split(':');
  116. if (values.Length > 1)
  117. remoteRef = values[1];
  118. }
  119. return remoteRef;
  120. }
  121. private bool PushChanges(IWin32Window owner)
  122. {
  123. if (PullFromUrl.Checked && string.IsNullOrEmpty(PushDestination.Text))
  124. {
  125. MessageBox.Show(owner, _selectDestinationDirectory.Text);
  126. return false;
  127. }
  128. if (PullFromRemote.Checked && string.IsNullOrEmpty(_NO_TRANSLATE_Remotes.Text))
  129. {
  130. MessageBox.Show(owner, _selectRemote.Text);
  131. return false;
  132. }
  133. if (TabControlTagBranch.SelectedTab == TagTab && string.IsNullOrEmpty(TagComboBox.Text) &&
  134. !PushAllTags.Checked)
  135. {
  136. MessageBox.Show(owner, _selectTag.Text);
  137. return false;
  138. }
  139. bool newBranch = false;
  140. //Extra check if the branch is already known to the remote, give a warning when not.
  141. //This is not possible when the remote is an URL, but this is ok since most users push to
  142. //known remotes anyway.
  143. if (TabControlTagBranch.SelectedTab == BranchTab && PullFromRemote.Checked)
  144. {
  145. //If the current branch is not the default push, and not known by the remote
  146. //(as far as we know since we are disconnected....)
  147. if (RemoteBranch.Text != GetDefaultPushRemote(_NO_TRANSLATE_Remotes.Text) &&
  148. !Settings.Module.GetHeads(true, true).Exists(x => x.Remote == _NO_TRANSLATE_Remotes.Text && x.LocalName == RemoteBranch.Text) )
  149. //Ask if this is really what the user wants
  150. if (MessageBox.Show(owner, _branchNewForRemote.Text, _pushCaption.Text, MessageBoxButtons.YesNo) ==
  151. DialogResult.No)
  152. {
  153. return false;
  154. }
  155. else
  156. {
  157. newBranch = true;
  158. }
  159. }
  160. Repositories.AddMostRecentRepository(PushDestination.Text);
  161. Settings.PushAllTags = PushAllTags.Checked;
  162. Settings.AutoPullOnRejected = AutoPullOnRejected.Checked;
  163. Settings.RecursiveSubmodulesCheck = RecursiveSubmodulesCheck.Checked;
  164. var remote = "";
  165. string destination;
  166. if (PullFromUrl.Checked)
  167. {
  168. destination = PushDestination.Text;
  169. }
  170. else
  171. {
  172. if (GitCommandHelpers.Plink())
  173. {
  174. if (!File.Exists(Settings.Pageant))
  175. MessageBox.Show(owner, _cannotLoadPutty.Text, PuttyText);
  176. else
  177. Settings.Module.StartPageantForRemote(_NO_TRANSLATE_Remotes.Text);
  178. }
  179. destination = _NO_TRANSLATE_Remotes.Text;
  180. remote = _NO_TRANSLATE_Remotes.Text.Trim();
  181. }
  182. string pushCmd;
  183. if (TabControlTagBranch.SelectedTab == BranchTab)
  184. {
  185. bool track = ReplaceTrackingReference.Checked;
  186. if (!track)
  187. {
  188. track = newBranch;
  189. string[] remotes = _NO_TRANSLATE_Remotes.DataSource as string[];
  190. if (remotes != null)
  191. foreach (string remoteBranch in remotes)
  192. if (!string.IsNullOrEmpty(remoteBranch) && _NO_TRANSLATE_Branch.Text.StartsWith(remoteBranch))
  193. track = false;
  194. }
  195. pushCmd = GitCommandHelpers.PushCmd(destination, _NO_TRANSLATE_Branch.Text, RemoteBranch.Text,
  196. PushAllBranches.Checked, ForcePushBranches.Checked, track, RecursiveSubmodulesCheck.Checked);
  197. }
  198. else if (TabControlTagBranch.SelectedTab == TagTab)
  199. pushCmd = GitCommandHelpers.PushTagCmd(destination, TagComboBox.Text, PushAllTags.Checked,
  200. ForcePushBranches.Checked);
  201. else
  202. {
  203. // Push Multiple Branches Tab selected
  204. var pushActions = new List<GitPushAction>();
  205. foreach (DataRow row in _branchTable.Rows)
  206. {
  207. var push = Convert.ToBoolean(row["Push"]);
  208. var force = Convert.ToBoolean(row["Force"]);
  209. var delete = Convert.ToBoolean(row["Delete"]);
  210. if (push || force)
  211. pushActions.Add(new GitPushAction(row["Local"].ToString(), row["Remote"].ToString(), force));
  212. else if (delete)
  213. pushActions.Add(new GitPushAction(row["Remote"].ToString()));
  214. }
  215. pushCmd = GitCommandHelpers.PushMultipleCmd(destination, pushActions);
  216. }
  217. ScriptManager.RunEventScripts(ScriptEvent.BeforePush);
  218. //controls can be accessed only from UI thread
  219. candidateForRebasingMergeCommit = Settings.PullMerge == Settings.PullAction.Rebase && PullFromRemote.Checked && !PushAllBranches.Checked && TabControlTagBranch.SelectedTab == BranchTab;
  220. selectedBranch = _NO_TRANSLATE_Branch.Text;
  221. selectedBranchRemote = _NO_TRANSLATE_Remotes.Text;
  222. selectedRemoteBranchName = RemoteBranch.Text;
  223. var form = new FormRemoteProcess(pushCmd)
  224. {
  225. Remote = remote,
  226. Text = string.Format(_pushToCaption.Text, destination),
  227. HandleOnExitCallback = HandlePushOnExit
  228. };
  229. form.ShowDialog(owner);
  230. if (!Settings.Module.InTheMiddleOfConflictedMerge() &&
  231. !Settings.Module.InTheMiddleOfRebase() && !form.ErrorOccurred())
  232. {
  233. ScriptManager.RunEventScripts(ScriptEvent.AfterPush);
  234. if (_createPullRequestCB.Checked)
  235. GitUICommands.Instance.StartCreatePullRequest(owner);
  236. return true;
  237. }
  238. return false;
  239. }
  240. private bool IsRebasingMergeCommit()
  241. {
  242. if (candidateForRebasingMergeCommit)
  243. {
  244. if (selectedBranch == _currentBranch && selectedBranchRemote == _currentBranchRemote)
  245. {
  246. string remoteBranchName = selectedBranchRemote + "/" + selectedRemoteBranchName;
  247. return Settings.Module.ExistsMergeCommit(remoteBranchName, selectedBranch);
  248. }
  249. else
  250. return false;
  251. }
  252. else
  253. return false;
  254. }
  255. private bool HandlePushOnExit(ref bool isError, FormProcess form)
  256. {
  257. if (isError)
  258. {
  259. //auto pull only if current branch was rejected
  260. Regex IsRejected = new Regex(Regex.Escape("! [rejected] ") + ".*" + Regex.Escape(_currentBranch) + ".*" + Regex.Escape(" (non-fast-forward)"), RegexOptions.Compiled);
  261. if (Settings.AutoPullOnRejected && IsRejected.IsMatch(form.OutputString.ToString()))
  262. {
  263. if (Settings.PullMerge == Settings.PullAction.Fetch)
  264. form.AppendOutputLine(Environment.NewLine + "Can not perform auto pull, when merge option is set to fetch.");
  265. else if (IsRebasingMergeCommit())
  266. form.AppendOutputLine(Environment.NewLine + "Can not perform auto pull, when merge option is set to rebase " + Environment.NewLine
  267. + "and one of the commits that are about to be rebased is a merge.");
  268. else
  269. {
  270. bool pullCompleted;
  271. GitUICommands.Instance.StartPullDialog(this, true, out pullCompleted);
  272. if (pullCompleted)
  273. {
  274. form.Retry();
  275. return true;
  276. }
  277. }
  278. }
  279. }
  280. return false;
  281. }
  282. private void FillPushDestinationDropDown()
  283. {
  284. PushDestination.DataSource = Repositories.RemoteRepositoryHistory.Repositories;
  285. PushDestination.DisplayMember = "Path";
  286. }
  287. private void UpdateBranchDropDown()
  288. {
  289. var curBranch = _NO_TRANSLATE_Branch.Text;
  290. _NO_TRANSLATE_Branch.DisplayMember = "Name";
  291. _NO_TRANSLATE_Branch.Items.Clear();
  292. _NO_TRANSLATE_Branch.Items.Add(HeadText);
  293. if (string.IsNullOrEmpty(curBranch))
  294. {
  295. curBranch = _currentBranch;
  296. if (curBranch.IndexOfAny("() ".ToCharArray()) != -1)
  297. curBranch = HeadText;
  298. }
  299. foreach (var head in Settings.Module.GetHeads(false, true))
  300. _NO_TRANSLATE_Branch.Items.Add(head);
  301. _NO_TRANSLATE_Branch.Text = curBranch;
  302. }
  303. private void PullClick(object sender, EventArgs e)
  304. {
  305. GitUICommands.Instance.StartPullDialog(this);
  306. }
  307. private void UpdateRemoteBranchDropDown()
  308. {
  309. RemoteBranch.DisplayMember = "Name";
  310. RemoteBranch.Items.Clear();
  311. if (!string.IsNullOrEmpty(_NO_TRANSLATE_Branch.Text))
  312. RemoteBranch.Items.Add(_NO_TRANSLATE_Branch.Text);
  313. foreach (var head in Settings.Module.GetHeads(false, true))
  314. if (!RemoteBranch.Items.Contains(head))
  315. RemoteBranch.Items.Add(head);
  316. }
  317. private void BranchSelectedValueChanged(object sender, EventArgs e)
  318. {
  319. if (_NO_TRANSLATE_Branch.Text != HeadText)
  320. {
  321. if (PullFromRemote.Checked)
  322. {
  323. var branch = _NO_TRANSLATE_Branch.SelectedItem as GitHead;
  324. if (branch != null && branch.TrackingRemote.Equals(_NO_TRANSLATE_Remotes.Text.Trim()))
  325. {
  326. RemoteBranch.Text = branch.MergeWith;
  327. if (!string.IsNullOrEmpty(RemoteBranch.Text))
  328. return;
  329. }
  330. }
  331. RemoteBranch.Text = _NO_TRANSLATE_Branch.Text;
  332. }
  333. }
  334. private void FormPushLoad(object sender, EventArgs e)
  335. {
  336. RestorePosition("push");
  337. _NO_TRANSLATE_Remotes.Select();
  338. Text = string.Concat(_pushCaption.Text, " (", Settings.WorkingDir, ")");
  339. var gitHoster = RepoHosts.TryGetGitHosterForCurrentWorkingDir();
  340. _createPullRequestCB.Enabled = gitHoster != null;
  341. }
  342. private void AddRemoteClick(object sender, EventArgs e)
  343. {
  344. GitUICommands.Instance.StartRemotesDialog(this);
  345. _NO_TRANSLATE_Remotes.DataSource = Settings.Module.GetRemotes();
  346. }
  347. private void PullFromRemoteCheckedChanged(object sender, EventArgs e)
  348. {
  349. BranchSelectedValueChanged(null, null);
  350. if (!PullFromRemote.Checked)
  351. return;
  352. PushDestination.Enabled = false;
  353. BrowseSource.Enabled = false;
  354. _NO_TRANSLATE_Remotes.Enabled = true;
  355. AddRemote.Enabled = true;
  356. }
  357. private void PullFromUrlCheckedChanged(object sender, EventArgs e)
  358. {
  359. if (!PullFromUrl.Checked)
  360. return;
  361. PushDestination.Enabled = true;
  362. BrowseSource.Enabled = true;
  363. _NO_TRANSLATE_Remotes.Enabled = false;
  364. AddRemote.Enabled = false;
  365. FillPushDestinationDropDown();
  366. }
  367. private void RemotesUpdated(object sender, EventArgs e)
  368. {
  369. if (TabControlTagBranch.SelectedTab == MultipleBranchTab)
  370. UpdateMultiBranchView();
  371. EnableLoadSshButton();
  372. var pushSettingValue = Settings.Module.GetSetting(string.Format("remote.{0}.push", _NO_TRANSLATE_Remotes.Text));
  373. if (PullFromRemote.Checked && !string.IsNullOrEmpty(pushSettingValue))
  374. {
  375. string defaultLocal = GetDefaultPushLocal(_NO_TRANSLATE_Remotes.Text);
  376. string defaultRemote = GetDefaultPushRemote(_NO_TRANSLATE_Remotes.Text);
  377. RemoteBranch.Text = "";
  378. if (!string.IsNullOrEmpty(defaultLocal))
  379. {
  380. var currentBranch = new GitHead(null, defaultLocal, _NO_TRANSLATE_Remotes.Text);
  381. _NO_TRANSLATE_Branch.Items.Add(currentBranch);
  382. _NO_TRANSLATE_Branch.SelectedItem = currentBranch;
  383. }
  384. if (!string.IsNullOrEmpty(defaultRemote))
  385. RemoteBranch.Text = defaultRemote;
  386. return;
  387. }
  388. if (string.IsNullOrEmpty(_NO_TRANSLATE_Branch.Text))
  389. {
  390. // Doing this makes it pretty easy to accidentally create a branch on the remote.
  391. // But leaving it blank will do the 'default' thing, meaning all branches are pushed.
  392. // Solution: when pushing a branch that doesn't exist on the remote, ask what to do
  393. var currentBranch = new GitHead(null, _currentBranch, _NO_TRANSLATE_Remotes.Text);
  394. _NO_TRANSLATE_Branch.Items.Add(currentBranch);
  395. _NO_TRANSLATE_Branch.SelectedItem = currentBranch;
  396. return;
  397. }
  398. BranchSelectedValueChanged(null, null);
  399. }
  400. private void EnableLoadSshButton()
  401. {
  402. LoadSSHKey.Visible = !string.IsNullOrEmpty(Settings.Module.GetPuttyKeyFileForRemote(_NO_TRANSLATE_Remotes.Text));
  403. }
  404. private void LoadSshKeyClick(object sender, EventArgs e)
  405. {
  406. if (!File.Exists(Settings.Pageant))
  407. MessageBox.Show(this, _cannotLoadPutty.Text, PuttyText);
  408. else
  409. Settings.Module.StartPageantForRemote(_NO_TRANSLATE_Remotes.Text);
  410. }
  411. private void RemotesValidated(object sender, EventArgs e)
  412. {
  413. EnableLoadSshButton();
  414. }
  415. private void FillTagDropDown()
  416. {
  417. TagComboBox.DisplayMember = "Name";
  418. var tags = Settings.Module.GetHeads(true, false);
  419. TagComboBox.DataSource = tags;
  420. }
  421. private void ForcePushBranchesCheckedChanged(object sender, EventArgs e)
  422. {
  423. ForcePushTags.Checked = ForcePushBranches.Checked;
  424. }
  425. private void ForcePushTagsCheckedChanged(object sender, EventArgs e)
  426. {
  427. ForcePushBranches.Checked = ForcePushTags.Checked;
  428. }
  429. private void PushAllBranchesCheckedChanged(object sender, EventArgs e)
  430. {
  431. _NO_TRANSLATE_Branch.Enabled = !PushAllBranches.Checked;
  432. RemoteBranch.Enabled = !PushAllBranches.Checked;
  433. }
  434. #region Multi-Branch Methods
  435. private DataTable _branchTable;
  436. private void UpdateMultiBranchView()
  437. {
  438. _branchTable = new DataTable();
  439. _branchTable.Columns.Add("Local", typeof (string));
  440. _branchTable.Columns.Add("Remote", typeof (string));
  441. _branchTable.Columns.Add("New", typeof (string));
  442. _branchTable.Columns.Add("Push", typeof(bool));
  443. _branchTable.Columns.Add("Force", typeof(bool));
  444. _branchTable.Columns.Add("Delete", typeof(bool));
  445. _branchTable.ColumnChanged += BranchTable_ColumnChanged;
  446. var bs = new BindingSource {DataSource = _branchTable};
  447. BranchGrid.DataSource = bs;
  448. string remote = _NO_TRANSLATE_Remotes.Text.Trim();
  449. if (remote == "")
  450. return;
  451. List<GitHead> localHeads = Settings.Module.GetHeads(false, true);
  452. List<GitHead> remoteHeads = Settings.Module.GetRemoteHeads(remote, false, true);
  453. // Add all the local branches.
  454. foreach (var head in localHeads)
  455. {
  456. DataRow row = _branchTable.NewRow();
  457. row["Force"] = false;
  458. row["Delete"] = false;
  459. row["Local"] = head.Name;
  460. string remoteName;
  461. if (head.Remote == remote)
  462. remoteName = head.MergeWith ?? head.Name;
  463. else
  464. remoteName = head.Name;
  465. row["Remote"] = remoteName;
  466. bool newAtRemote = remoteHeads.Any(h => h.Name == remoteName);
  467. row["New"] = newAtRemote ? _no.Text : _yes.Text;
  468. row["Push"] = newAtRemote;
  469. _branchTable.Rows.Add(row);
  470. }
  471. // Offer to delete all the left over remote branches.
  472. foreach (var remoteHead in remoteHeads)
  473. {
  474. GitHead head = remoteHead;
  475. if (!localHeads.Any(h => h.Name == head.Name))
  476. {
  477. DataRow row = _branchTable.NewRow();
  478. row["Local"] = null;
  479. row["Remote"] = remoteHead.Name;
  480. row["New"] = _no.Text;
  481. row["Push"] = false;
  482. row["Force"] = false;
  483. row["Delete"] = false;
  484. _branchTable.Rows.Add(row);
  485. }
  486. }
  487. }
  488. static void BranchTable_ColumnChanged(object sender, DataColumnChangeEventArgs e)
  489. {
  490. if (e.Column.ColumnName == "Push" && (bool)e.ProposedValue)
  491. {
  492. e.Row["Force"] = false;
  493. e.Row["Delete"] = false;
  494. }
  495. if (e.Column.ColumnName == "Force" && (bool)e.ProposedValue)
  496. {
  497. e.Row["Push"] = false;
  498. e.Row["Delete"] = false;
  499. }
  500. if (e.Column.ColumnName == "Delete" && (bool)e.ProposedValue)
  501. {
  502. e.Row["Push"] = false;
  503. e.Row["Force"] = false;
  504. }
  505. }
  506. private void TabControlTagBranch_Selected(object sender, TabControlEventArgs e)
  507. {
  508. if (TabControlTagBranch.SelectedTab == MultipleBranchTab)
  509. UpdateMultiBranchView();
  510. else if (TabControlTagBranch.SelectedTab == TagTab)
  511. FillTagDropDown();
  512. else
  513. {
  514. UpdateBranchDropDown();
  515. UpdateRemoteBranchDropDown();
  516. }
  517. }
  518. private void BranchGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
  519. {
  520. // Push grid checkbox changes immediately into the underlying data table.
  521. if (BranchGrid.CurrentCell is DataGridViewCheckBoxCell)
  522. {
  523. BranchGrid.EndEdit();
  524. ((BindingSource)BranchGrid.DataSource).EndEdit();
  525. }
  526. }
  527. #endregion
  528. private void FormPush_FormClosing(object sender, FormClosingEventArgs e)
  529. {
  530. SavePosition("push");
  531. }
  532. private void ShowOptions_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  533. {
  534. PushOptionsPanel.Visible = true;
  535. ShowOptions.Visible = false;
  536. SetFormSizeToFitAllItems();
  537. }
  538. private void ShowTagOptions_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  539. {
  540. TagOptionsPanel.Visible = true;
  541. ShowTagOptions.Visible = false;
  542. SetFormSizeToFitAllItems();
  543. }
  544. private void SetFormSizeToFitAllItems()
  545. {
  546. this.Size = new System.Drawing.Size(this.MinimumSize.Width, this.MinimumSize.Height + 70);
  547. }
  548. }
  549. }