using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using NaGet.Packages; namespace AppliStation { /// /// ユーザ設定用フォーム /// public partial class UserPrefForm : Form { private List repos; private bool isRepoListChanged; /// /// コンストラクタ /// public UserPrefForm() { repos = new List(); InitializeComponent(); this.openInternetOptionLinkAdminLabel.Visible = ! NaGet.Utils.IsAdministrators(); AppliStation.Util.NativeMethods.LinkLabel_SetElevationRequiredState(this.openInternetOptionLinkAdminLabel, true); loadCurrentPref(); } /// /// 現在の設定を読み込む /// public void loadCurrentPref() { this.RepositoriesListSetting = NaGet.Utils.GetDeserializedObject(NaGet.Env.RepositoriesListFile); NaGet.NaGetLibPref userPref = NaGet.Env.Pref; this.ProxyAddress = userPref.ProxyAddress; this.EnableScanInstallerFile = userPref.EnableScanInstallerFile; this.InstallOnBackground = userPref.InstallOnBackground; this.CacheFolder = userPref.CacheFolder; } #region レポジトリリスト設定関連 /// /// レポジトリリストの設定を読み書きする /// public RepositoriesList RepositoriesListSetting { get { RepositoriesList repoList = new RepositoriesList(); repoList.Repositories = repos.ToArray(); return repoList; } set { repos.Clear(); repos.AddRange(value.Repositories); updateRepos(); // レポジトリ変更状態をリセットする isRepoListChanged = false; } } /// /// ListBoxへ表示するレポジトリ表現文字列を返す /// /// 対象レポジトリ /// ListBoxに表示すべき文字列 private static string repoListCheckedListBoxRenderer(RepositoryInfo repo) { return string.Format("{0}[{1}]", repo.Name, repo.Url.Href); } /// /// ListBoxの内容を更新(再構築)する。 /// private void updateRepos() { repoListCheckedListBox.Items.Clear(); foreach (RepositoryInfo repo in repos) { string label = repoListCheckedListBoxRenderer(repo); repoListCheckedListBox.Items.Add(label, repo.Enabled); } } void RepoListCheckedListBoxSelectedIndexChanged(object sender, EventArgs e) { int selectedIndex = repoListCheckedListBox.SelectedIndex; bool selected = (selectedIndex >= 0); removeRepoButton.Enabled = selected; upRepoButton.Enabled = selected && ((1 <= selectedIndex) && (selectedIndex < repos.Count)); downRepoButton.Enabled = selected && ((0 <= selectedIndex) && (selectedIndex < (repos.Count-1))); repoUrlLabel.Enabled = selected; repoUrlTextBox.Enabled = selected; if (selected) { repoUrlTextBox.Text = repos[repoListCheckedListBox.SelectedIndex].Url.Href; repoUrlTextBox.SelectAll(); } else { repoUrlTextBox.Clear(); } } void AddRepoButtonClick(object sender, EventArgs e) { RepositoryInfo repo = new RepositoryInfo(); repo.Name = string.Format("新しいレポジトリ"); repo.Url = new LocationEntry(); repo.Enabled = true; repos.Add(repo); updateRepos(); repoListCheckedListBox.SelectedIndex = repos.Count - 1; isRepoListChanged = true; } void RepoListCheckedListBoxItemCheck(object sender, ItemCheckEventArgs e) { repos[e.Index].Enabled = (e.NewValue == CheckState.Checked); isRepoListChanged = true; } void RemoveRepoButtonClick(object sender, EventArgs e) { int selectedIndex = repoListCheckedListBox.SelectedIndex; if ((0 <= selectedIndex) && (selectedIndex < repos.Count)) { string text = string.Format("本当にレポジトリ「{0}」を消去しますか?", repos[selectedIndex].Name); DialogResult result = MessageBox.Show(text, "レポジトリの削除", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (result == DialogResult.OK) { repos.RemoveAt(selectedIndex); repoListCheckedListBox.Items.RemoveAt(selectedIndex); isRepoListChanged = true; } } } void UpRepoButtonClick(object sender, EventArgs e) { int selectedIndex = repoListCheckedListBox.SelectedIndex; if ((1 <= selectedIndex) && (selectedIndex < repos.Count)) { NaGet.Utils.ListSwap(repos, selectedIndex-1, selectedIndex); AppliStation.Util.GUIUtils.CheckedListBox_SwapItems(repoListCheckedListBox, selectedIndex-1, selectedIndex); repoListCheckedListBox.SelectedIndex --; isRepoListChanged = true; } } void DownRepoButtonClick(object sender, EventArgs e) { int selectedIndex = repoListCheckedListBox.SelectedIndex; if ((0 <= selectedIndex) && (selectedIndex < (repos.Count-1))) { NaGet.Utils.ListSwap(repos, selectedIndex, selectedIndex+1); AppliStation.Util.GUIUtils.CheckedListBox_SwapItems(repoListCheckedListBox, selectedIndex, selectedIndex+1); repoListCheckedListBox.SelectedIndex ++; isRepoListChanged = true; } } void RepoUrlTextBoxLeave(object sender, EventArgs e) { int selectedIndex = repoListCheckedListBox.SelectedIndex; if ((0 <= selectedIndex) && (selectedIndex < repos.Count)) { if (repoUrlTextBox.Text != repos[selectedIndex].Url.Href) { repos[selectedIndex].Url = new LocationEntry(repoUrlTextBox.Text); repoListCheckedListBox.Items[selectedIndex] = repoListCheckedListBoxRenderer(repos[selectedIndex]); isRepoListChanged = true; } } } /// /// レポジトリリストが編集されたか否かのフラグ /// /// ソフトリストの再読み込みが必要か否かの判断に使われる public bool IsRepositoryListSettingChanged { get { return isRepoListChanged; } } /// /// レポジトリリストの設定を反映する /// private void commitRepositoryListSetting() { if (isRepoListChanged) { NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, this.RepositoriesListSetting); } } #endregion #region プロキシサーバ設定関連 /// /// プロキシアドレスを設定あるいは取得する /// public string ProxyAddress { get { if (proxySameAsIERadioButton.Checked) { return string.Empty; } else if (directConnRadioButton.Checked) { return "-"; } else { return proxyURLTextBox.Text; } } set { if (string.IsNullOrEmpty(value)) { proxySameAsIERadioButton.Checked = true; } else if ("-" == value) { directConnRadioButton.Checked = true; } else { specifyProxyRadioButton.Checked = true; proxyURLTextBox.Text = value; } updateProxyURLEnability(); } } /// /// ProxyURLのテキストボックス領域の有効状態を切り替える /// private void updateProxyURLEnability() { bool isSpecifiedProxy = specifyProxyRadioButton.Checked; proxyURLLabel.Enabled = isSpecifiedProxy; proxyURLTextBox.Enabled = isSpecifiedProxy; } void ProxyRadioButtonsCheckedChanged(object sender, EventArgs e) { updateProxyURLEnability(); } void OpenInternetOptionLinkLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { string verb = "open"; if (sender == openInternetOptionLinkAdminLabel) { verb = "runas"; } try { ProcessStartInfo procInfo = new ProcessStartInfo("control.exe"); procInfo.Arguments = "inetcpl.cpl,,4"; procInfo.UseShellExecute = true; procInfo.Verb = verb; Process.Start(procInfo); } catch (System.ComponentModel.Win32Exception ex) { MessageBox.Show(ex.Message, "インターネットオプション", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception) { MessageBox.Show("インターネットオプションが開けませんでした", "インターネットオプション", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// プロキシ設定を、指定された設定オブジェクトに設定する。 /// /// 設定オブジェクト private void commitProxySetting(NaGet.NaGetLibPref pref) { pref.ProxyAddress = this.ProxyAddress; } #endregion #region インストール設定関連 /// /// インストーラーファイルをウイルススキャンするかを設定あるいは取得する /// public bool EnableScanInstallerFile { set { this.installScanInstallerFileCheckbox.Checked = value; } get { return this.installScanInstallerFileCheckbox.Checked; } } /// /// インストール・アンインストールを優先度を下げて実行するかを設定あるいは取得する /// public bool InstallOnBackground { set { this.installOnBackgroundCheckBox.Checked = value; } get { return this.installOnBackgroundCheckBox.Checked; } } public string CacheFolder { set { if (string.IsNullOrEmpty(value)) { this.cacheFolderCustomCheckBox.Checked = false; this.cacheFolderTextBox.Text = string.Empty; } else { this.cacheFolderCustomCheckBox.Checked = true; this.cacheFolderTextBox.Text = value; } } get { if (this.cacheFolderCustomCheckBox.Checked) { return this.cacheFolderTextBox.Text; } else { return null; } } } /// /// インストール関連設定を、指定された設定オブジェクトに設定する。 /// /// 設定オブジェクト private void commitInstallSetting(NaGet.NaGetLibPref pref) { pref.EnableScanInstallerFile = this.EnableScanInstallerFile; pref.InstallOnBackground = this.InstallOnBackground; pref.CacheFolder = this.CacheFolder; } #endregion /// /// 指定された設定オブジェクトをファイルとして保存する /// /// 設定ファイル private static void commitNaGetLibPref(NaGet.NaGetLibPref pref) { // ファイルに書き込む string path = NaGet.Env.PrefPath; NaGet.Utils.PutSerializeObject(path, pref); // 設定についてファイルから設定を再読み込みさせる NaGet.Env.LoadPref(); } void OkButtonClick(object sender, EventArgs e) { NaGet.NaGetLibPref pref = NaGet.Env.Pref; commitRepositoryListSetting(); commitProxySetting(pref); commitInstallSetting(pref); commitNaGetLibPref(pref); } void CancelButtonClick(object sender, EventArgs e) { } void RepoUrlTextBoxValidating(object sender, System.ComponentModel.CancelEventArgs e) { string urlText = repoUrlTextBox.Text; if (string.IsNullOrEmpty(urlText)) { return; // special case. } if (Uri.IsWellFormedUriString(urlText, UriKind.Absolute) == false) { errorProvider.SetError(repoUrlLabel, "URLの記述が不正です"); e.Cancel = true; } else { Uri uri = new Uri(urlText); if ((uri.Scheme != Uri.UriSchemeFile) && (uri.Scheme != Uri.UriSchemeFtp) && (uri.Scheme != Uri.UriSchemeHttp) && (uri.Scheme != Uri.UriSchemeHttps)){ errorProvider.SetError(repoUrlLabel, "URLの記述が不正です"); e.Cancel = true; } else { errorProvider.Clear(); } } } void CacheFolderCustomCheckBoxCheckedChanged(object sender, EventArgs e) { cacheFolderTextBox.Enabled = cacheFolderCustomCheckBox.Checked; cacheFolderBrowseButton.Enabled = cacheFolderCustomCheckBox.Checked; } void CacheFolderBrowseButtonClick(object sender, EventArgs e) { string pwd = System.IO.Directory.GetCurrentDirectory(); FolderBrowserDialog fd = new FolderBrowserDialog(); fd.Description = "キャッシュフォルダーを指定してください。"; fd.SelectedPath = cacheFolderTextBox.Text; fd.ShowNewFolderButton = true; if (fd.ShowDialog(this) == DialogResult.OK) { cacheFolderTextBox.Text = fd.SelectedPath; } System.IO.Directory.SetCurrentDirectory(pwd); // ダイアログで変わったカレントディレクトリを元に戻す } void CacheFolderTextBoxValidating(object sender, System.ComponentModel.CancelEventArgs e) { string folderPath = cacheFolderTextBox.Text; if (string.IsNullOrEmpty(folderPath)) { errorProvider.Clear(); return; // special case } else if (! System.IO.Directory.Exists(folderPath)) { errorProvider.SetError(cacheFolderTextBox, "存在しないフォルダーパスを指定しています。"); e.Cancel = true; } else { errorProvider.Clear(); } } void CacheFolderOpenLinkLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { string folderPath; if (cacheFolderCustomCheckBox.Checked) { folderPath = cacheFolderTextBox.Text; } else { // デフォルトは AppDataFolderPath/Cache。 folderPath = System.IO.Path.Combine(NaGet.Env.AppDataFolderPath, "Cache"); } if (System.IO.Directory.Exists(folderPath)) { try { Process.Start(folderPath); } catch (Exception ex) { MessageBox.Show(ex.Message, "キャッシュフォルダー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show(string.Format("フォルダーパス\"{0}\"は存在しませんでした。", folderPath), "キャッシュフォルダー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }