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()
{
try {
this.RepositoriesListSetting = NaGet.Utils.GetDeserializedObject(NaGet.Env.RepositoriesListFile);
} catch {
this.RepositoriesListSetting = new RepositoriesList();
}
NaGet.NaGetLibPref userPref = NaGet.Env.Pref;
this.ProxyAddress = userPref.ProxyAddress;
this.EnableScanInstallerFile = userPref.EnableScanInstallerFile;
this.InstallOnBackground = userPref.InstallOnBackground;
this.CacheFolder = userPref.CacheFolder;
this.ExcludeUpdatePackageNames = userPref.ExcludeUpdatePackageNames;
}
#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 RepoUrlTextBoxValidated(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
#region ソフト更新設定関連
public string[] ExcludeUpdatePackageNames {
set {
this.upgradeExcludeTextBox.Lines = value;
}
get {
List list = new List();
foreach (string line in this.upgradeExcludeTextBox.Lines) {
if (!string.IsNullOrEmpty(line)) {
list.Add(line);
}
}
return list.ToArray();
}
}
///
/// ソフト更新関連設定を、指定された設定オブジェクトに設定する。
///
/// 設定オブジェクト
private void commitUpgradeSetting(NaGet.NaGetLibPref pref)
{
pref.ExcludeUpdatePackageNames = this.ExcludeUpdatePackageNames;
}
#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);
commitUpgradeSetting(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);
}
}
void CacheFolderClearLinkLabelLinkClicked(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)) {
DialogResult result = MessageBox.Show(string.Format("フォルダーパス\"{0}\"のファイルを削除して構いませんか?", folderPath), "キャッシュフォルダー", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (result == DialogResult.OK) {
foreach (string targetDir in System.IO.Directory.GetDirectories(folderPath)) {
try {
NaGet.Utils.SetAttributeRecursive(targetDir, System.IO.FileAttributes.Normal);
System.IO.Directory.Delete(targetDir, true);
} catch {
// 何もせずに静かに先に進む
}
}
}
} else {
MessageBox.Show(string.Format("フォルダーパス\"{0}\"は存在しませんでした。", folderPath), "キャッシュフォルダー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}