OSDN Git Service

8005bf322694210db1ac760792b33a3b84235b43
[applistation/AppliStation.git] / AppliStation / UserPrefForm.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Drawing;\r
4 using System.Windows.Forms;\r
5 using System.Diagnostics;\r
6 \r
7 using NaGet.Packages;\r
8 \r
9 namespace AppliStation\r
10 {\r
11         /// <summary>\r
12         /// ユーザ設定用フォーム\r
13         /// </summary>\r
14         public partial class UserPrefForm : Form\r
15         {\r
16                 private List<RepositoryInfo> repos;\r
17                 \r
18                 private bool isRepoListChanged;\r
19                 \r
20                 /// <summary>\r
21                 /// コンストラクタ\r
22                 /// </summary>\r
23                 public UserPrefForm()\r
24                 {\r
25                         repos = new List<RepositoryInfo>();\r
26                         \r
27                         InitializeComponent();\r
28                         \r
29                         this.openInternetOptionLinkAdminLabel.Visible = ! NaGet.Utils.IsAdministrators();\r
30                         AppliStation.Util.NativeMethods.LinkLabel_SetElevationRequiredState(this.openInternetOptionLinkAdminLabel, true);\r
31                         \r
32                         loadCurrentPref();\r
33                 }\r
34                 \r
35                 /// <summary>\r
36                 /// 現在の設定を読み込む\r
37                 /// </summary>\r
38                 public void loadCurrentPref()\r
39                 {\r
40                         this.RepositoriesListSetting = NaGet.Utils.GetDeserializedObject<RepositoriesList>(NaGet.Env.RepositoriesListFile);\r
41                         \r
42                         NaGet.NaGetLibPref userPref = NaGet.Env.Pref;\r
43                         this.ProxyAddress = userPref.ProxyAddress;\r
44                         this.EnableScanInstallerFile = userPref.EnableScanInstallerFile;\r
45                         this.InstallOnBackground = userPref.InstallOnBackground;\r
46                         this.CacheFolder = userPref.CacheFolder;\r
47                         this.ExcludeUpdatePackageNames = userPref.ExcludeUpdatePackageNames;\r
48                 }\r
49                 \r
50                 #region レポジトリリスト設定関連\r
51                 \r
52                 /// <summary>\r
53                 /// レポジトリリストの設定を読み書きする\r
54                 /// </summary>\r
55                 public RepositoriesList RepositoriesListSetting {\r
56                         get {\r
57                                 RepositoriesList repoList = new RepositoriesList();\r
58                                 repoList.Repositories = repos.ToArray();\r
59                                 return repoList;\r
60                         }\r
61                         set {\r
62                                 repos.Clear();\r
63                                 repos.AddRange(value.Repositories);\r
64                                 \r
65                                 updateRepos();\r
66                                 \r
67                                 // レポジトリ変更状態をリセットする\r
68                                 isRepoListChanged = false;\r
69                         }\r
70                 }\r
71                 \r
72                 /// <summary>\r
73                 /// ListBoxへ表示するレポジトリ表現文字列を返す\r
74                 /// </summary>\r
75                 /// <param name="repo">対象レポジトリ</param>\r
76                 /// <returns>ListBoxに表示すべき文字列</returns>\r
77                 private static string repoListCheckedListBoxRenderer(RepositoryInfo repo) {\r
78                         return string.Format("{0}[{1}]", repo.Name, repo.Url.Href);\r
79                 }\r
80 \r
81                 /// <summary>\r
82                 /// ListBoxの内容を更新(再構築)する。\r
83                 /// </summary>\r
84                 private void updateRepos()\r
85                 {\r
86                         repoListCheckedListBox.Items.Clear();\r
87                         \r
88                         foreach (RepositoryInfo repo in repos) {\r
89                                 string label = repoListCheckedListBoxRenderer(repo);\r
90                                 repoListCheckedListBox.Items.Add(label, repo.Enabled);\r
91                         }\r
92                 }\r
93                 \r
94                 void RepoListCheckedListBoxSelectedIndexChanged(object sender, EventArgs e)\r
95                 {\r
96                         int selectedIndex = repoListCheckedListBox.SelectedIndex;\r
97                         bool selected = (selectedIndex >= 0);\r
98                         \r
99                         removeRepoButton.Enabled        = selected;\r
100                         upRepoButton.Enabled            = selected && ((1 <= selectedIndex) && (selectedIndex < repos.Count));\r
101                         downRepoButton.Enabled          = selected && ((0 <= selectedIndex) && (selectedIndex < (repos.Count-1)));\r
102                         repoUrlLabel.Enabled            = selected;\r
103                         repoUrlTextBox.Enabled          = selected;\r
104                         if (selected) {\r
105                                 repoUrlTextBox.Text = repos[repoListCheckedListBox.SelectedIndex].Url.Href;\r
106                                 repoUrlTextBox.SelectAll();\r
107                         } else {\r
108                                 repoUrlTextBox.Clear();\r
109                         }\r
110                 }\r
111                 \r
112                 void AddRepoButtonClick(object sender, EventArgs e)\r
113                 {\r
114                         RepositoryInfo repo = new RepositoryInfo();\r
115                         repo.Name = string.Format("新しいレポジトリ");\r
116                         repo.Url = new LocationEntry();\r
117                         repo.Enabled = true;\r
118                         \r
119                         repos.Add(repo);\r
120                         \r
121                         updateRepos();\r
122                         repoListCheckedListBox.SelectedIndex = repos.Count - 1;\r
123                         \r
124                         isRepoListChanged = true;\r
125                 }\r
126                 \r
127                 void RepoListCheckedListBoxItemCheck(object sender, ItemCheckEventArgs e)\r
128                 {\r
129                         repos[e.Index].Enabled = (e.NewValue == CheckState.Checked);\r
130                         \r
131                         isRepoListChanged = true;\r
132                 }\r
133                 \r
134                 void RemoveRepoButtonClick(object sender, EventArgs e)\r
135                 {\r
136                         int selectedIndex = repoListCheckedListBox.SelectedIndex;\r
137                         if ((0 <= selectedIndex) && (selectedIndex < repos.Count)) {\r
138                                 string text = string.Format("本当にレポジトリ「{0}」を消去しますか?", repos[selectedIndex].Name);\r
139                                 DialogResult result = MessageBox.Show(text, "レポジトリの削除", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);\r
140                                 if (result == DialogResult.OK) {\r
141                                         repos.RemoveAt(selectedIndex);\r
142                                         repoListCheckedListBox.Items.RemoveAt(selectedIndex);\r
143                                         \r
144                                         isRepoListChanged = true;\r
145                                 }\r
146                         }\r
147                 }\r
148                 \r
149                 void UpRepoButtonClick(object sender, EventArgs e)\r
150                 {\r
151                         int selectedIndex = repoListCheckedListBox.SelectedIndex;\r
152                         if ((1 <= selectedIndex) && (selectedIndex < repos.Count)) {\r
153                                 NaGet.Utils.ListSwap(repos, selectedIndex-1, selectedIndex);\r
154                                 AppliStation.Util.GUIUtils.CheckedListBox_SwapItems(repoListCheckedListBox, selectedIndex-1, selectedIndex);\r
155                                 repoListCheckedListBox.SelectedIndex --;\r
156                                 \r
157                                 isRepoListChanged = true;\r
158                         }\r
159                 }\r
160                 \r
161                 void DownRepoButtonClick(object sender, EventArgs e)\r
162                 {\r
163                         int selectedIndex = repoListCheckedListBox.SelectedIndex;\r
164                         if ((0 <= selectedIndex) && (selectedIndex < (repos.Count-1))) {\r
165                                 NaGet.Utils.ListSwap(repos, selectedIndex, selectedIndex+1);\r
166                                 AppliStation.Util.GUIUtils.CheckedListBox_SwapItems(repoListCheckedListBox, selectedIndex, selectedIndex+1);\r
167                                 repoListCheckedListBox.SelectedIndex ++;\r
168                                 \r
169                                 isRepoListChanged = true;\r
170                         }\r
171                 }\r
172                 \r
173                 void RepoUrlTextBoxValidated(object sender, EventArgs e)\r
174                 {\r
175                         int selectedIndex = repoListCheckedListBox.SelectedIndex;\r
176                         if ((0 <= selectedIndex) && (selectedIndex < repos.Count)) {\r
177                                 if (repoUrlTextBox.Text != repos[selectedIndex].Url.Href) {\r
178                                         repos[selectedIndex].Url = new LocationEntry(repoUrlTextBox.Text);\r
179                                         repoListCheckedListBox.Items[selectedIndex] = repoListCheckedListBoxRenderer(repos[selectedIndex]);\r
180                                         \r
181                                         isRepoListChanged = true;\r
182                                 }\r
183                         }\r
184                 }\r
185                 \r
186                 /// <summary>\r
187                 /// レポジトリリストが編集されたか否かのフラグ\r
188                 /// </summary>\r
189                 /// <remarks>ソフトリストの再読み込みが必要か否かの判断に使われる</remarks>\r
190                 public bool IsRepositoryListSettingChanged {\r
191                         get { return isRepoListChanged; }\r
192                 }\r
193                 \r
194                 /// <summary>\r
195                 /// レポジトリリストの設定を反映する\r
196                 /// </summary>\r
197                 private void commitRepositoryListSetting()\r
198                 {\r
199                         if (isRepoListChanged) {\r
200                                 NaGet.Utils.PutSerializeObject<RepositoriesList>(NaGet.Env.RepositoriesListFile, this.RepositoriesListSetting);\r
201                         }\r
202                 }\r
203                 \r
204                 #endregion\r
205                 \r
206                 #region プロキシサーバ設定関連\r
207 \r
208                 /// <summary>\r
209                 /// プロキシアドレスを設定あるいは取得する\r
210                 /// </summary>\r
211                 public string ProxyAddress {\r
212                         get {\r
213                                 if (proxySameAsIERadioButton.Checked) {\r
214                                         return string.Empty;    \r
215                                 } else if (directConnRadioButton.Checked) {\r
216                                         return "-";\r
217                                 } else {\r
218                                         return proxyURLTextBox.Text;\r
219                                 }\r
220                         }\r
221                         set {\r
222                                 if (string.IsNullOrEmpty(value)) {\r
223                                         proxySameAsIERadioButton.Checked = true;        \r
224                                 } else if ("-" == value) {\r
225                                         directConnRadioButton.Checked = true;\r
226                                 } else {\r
227                                         specifyProxyRadioButton.Checked = true;\r
228                                         proxyURLTextBox.Text = value;\r
229                                 }\r
230                                 \r
231                                 updateProxyURLEnability();\r
232                         }\r
233                 }\r
234                 \r
235                 /// <summary>\r
236                 /// ProxyURLのテキストボックス領域の有効状態を切り替える\r
237                 /// </summary>\r
238                 private void updateProxyURLEnability()\r
239                 {\r
240                         bool isSpecifiedProxy = specifyProxyRadioButton.Checked;\r
241                         \r
242                         proxyURLLabel.Enabled   = isSpecifiedProxy;\r
243                         proxyURLTextBox.Enabled = isSpecifiedProxy;\r
244                 }\r
245                 \r
246                 void ProxyRadioButtonsCheckedChanged(object sender, EventArgs e)\r
247                 {\r
248                         updateProxyURLEnability();\r
249                 }\r
250                 \r
251                 void OpenInternetOptionLinkLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\r
252                 {\r
253                         string verb = "open";\r
254                         \r
255                         if (sender == openInternetOptionLinkAdminLabel) {\r
256                                 verb = "runas"; \r
257                         }\r
258                         \r
259                         try {\r
260                                 ProcessStartInfo procInfo = new ProcessStartInfo("control.exe");\r
261                                 procInfo.Arguments = "inetcpl.cpl,,4";\r
262                                 procInfo.UseShellExecute = true;\r
263                                 procInfo.Verb = verb;\r
264                                 \r
265                                 Process.Start(procInfo);\r
266                         } catch (System.ComponentModel.Win32Exception ex) {\r
267                                 MessageBox.Show(ex.Message, "インターネットオプション", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
268                         } catch (Exception) {\r
269                                 MessageBox.Show("インターネットオプションが開けませんでした", "インターネットオプション", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
270                         }\r
271                 }\r
272                 \r
273                 /// <summary>\r
274                 /// プロキシ設定を、指定された設定オブジェクトに設定する。\r
275                 /// </summary>\r
276                 /// <param name="pref">設定オブジェクト</param>\r
277                 private void commitProxySetting(NaGet.NaGetLibPref pref)\r
278                 {\r
279                         pref.ProxyAddress = this.ProxyAddress;\r
280                 }\r
281                 \r
282                 #endregion\r
283                 \r
284                 #region インストール設定関連\r
285                 \r
286                 /// <summary>\r
287                 /// インストーラーファイルをウイルススキャンするかを設定あるいは取得する\r
288                 /// </summary>\r
289                 public bool EnableScanInstallerFile {\r
290                         set {   this.installScanInstallerFileCheckbox.Checked = value;  }\r
291                         get {   return this.installScanInstallerFileCheckbox.Checked;   }\r
292                 }\r
293                 \r
294                 /// <summary>\r
295                 /// インストール・アンインストールを優先度を下げて実行するかを設定あるいは取得する\r
296                 /// </summary>\r
297                 public bool InstallOnBackground {\r
298                         set {   this.installOnBackgroundCheckBox.Checked = value;       }\r
299                         get {   return this.installOnBackgroundCheckBox.Checked;        }\r
300                 }\r
301                 \r
302                 public string CacheFolder {\r
303                         set {\r
304                                 if (string.IsNullOrEmpty(value)) {\r
305                                         this.cacheFolderCustomCheckBox.Checked = false;\r
306                                         this.cacheFolderTextBox.Text = string.Empty;\r
307                                 } else {\r
308                                         this.cacheFolderCustomCheckBox.Checked = true;\r
309                                         this.cacheFolderTextBox.Text = value;\r
310                                 }\r
311                         }\r
312                         get {\r
313                                 if (this.cacheFolderCustomCheckBox.Checked) {\r
314                                         return this.cacheFolderTextBox.Text;\r
315                                 } else {\r
316                                         return null;\r
317                                 }\r
318                         }\r
319                 }\r
320                 \r
321                 /// <summary>\r
322                 /// インストール関連設定を、指定された設定オブジェクトに設定する。\r
323                 /// </summary>\r
324                 /// <param name="pref">設定オブジェクト</param>\r
325                 private void commitInstallSetting(NaGet.NaGetLibPref pref)\r
326                 {\r
327                         pref.EnableScanInstallerFile = this.EnableScanInstallerFile;\r
328                         pref.InstallOnBackground = this.InstallOnBackground;\r
329                         pref.CacheFolder = this.CacheFolder;\r
330                 }\r
331                 \r
332                 #endregion\r
333                 \r
334                 #region ソフト更新設定関連\r
335                 \r
336                 \r
337                 public string[] ExcludeUpdatePackageNames {\r
338                         set {\r
339                                 this.upgradeExcludeTextBox.Lines = value;\r
340                         }\r
341                         get {\r
342                                 List<string> list = new List<string>();\r
343                                 \r
344                                 foreach (string line in this.upgradeExcludeTextBox.Lines) {\r
345                                         if (!string.IsNullOrEmpty(line)) {\r
346                                                 list.Add(line);\r
347                                         }\r
348                                 }\r
349                                 \r
350                                 return list.ToArray();\r
351                         }\r
352                 }\r
353                 \r
354                 /// <summary>\r
355                 /// ソフト更新関連設定を、指定された設定オブジェクトに設定する。\r
356                 /// </summary>\r
357                 /// <param name="pref">設定オブジェクト</param>\r
358                 private void commitUpgradeSetting(NaGet.NaGetLibPref pref)\r
359                 {\r
360                         pref.ExcludeUpdatePackageNames = this.ExcludeUpdatePackageNames;\r
361                 }\r
362                 \r
363                 #endregion\r
364                 \r
365                 /// <summary>\r
366                 /// 指定された設定オブジェクトをファイルとして保存する\r
367                 /// </summary>\r
368                 /// <param name="pref">設定ファイル</param>\r
369                 private static void commitNaGetLibPref(NaGet.NaGetLibPref pref)\r
370                 {\r
371                         // ファイルに書き込む\r
372                         string path = NaGet.Env.PrefPath;\r
373                         NaGet.Utils.PutSerializeObject<NaGet.NaGetLibPref>(path, pref);\r
374                         \r
375                         // 設定についてファイルから設定を再読み込みさせる\r
376                         NaGet.Env.LoadPref();\r
377                 }\r
378                 \r
379                 void OkButtonClick(object sender, EventArgs e)\r
380                 {\r
381                         NaGet.NaGetLibPref pref = NaGet.Env.Pref;\r
382                         \r
383                         commitRepositoryListSetting();\r
384                         commitProxySetting(pref);\r
385                         commitInstallSetting(pref);\r
386                         commitUpgradeSetting(pref);\r
387                         \r
388                         commitNaGetLibPref(pref);\r
389                 }\r
390                 \r
391                 void CancelButtonClick(object sender, EventArgs e)\r
392                 {\r
393                 }\r
394                 \r
395                 void RepoUrlTextBoxValidating(object sender, System.ComponentModel.CancelEventArgs e)\r
396                 {\r
397                         string urlText = repoUrlTextBox.Text;\r
398                         \r
399                         if (string.IsNullOrEmpty(urlText)) {\r
400                                 return; // special case.\r
401                         } if (Uri.IsWellFormedUriString(urlText, UriKind.Absolute) == false) {\r
402                                 errorProvider.SetError(repoUrlLabel, "URLの記述が不正です");\r
403                                 e.Cancel = true;\r
404                         } else {\r
405                                 Uri uri = new Uri(urlText);\r
406                                 if ((uri.Scheme != Uri.UriSchemeFile) &&\r
407                                     (uri.Scheme != Uri.UriSchemeFtp) &&\r
408                                     (uri.Scheme != Uri.UriSchemeHttp) &&\r
409                                     (uri.Scheme != Uri.UriSchemeHttps)){\r
410                                         errorProvider.SetError(repoUrlLabel, "URLの記述が不正です");\r
411                                         e.Cancel = true;\r
412                                 } else {\r
413                                         errorProvider.Clear();\r
414                                 }\r
415                         }\r
416                 }\r
417                 \r
418                 \r
419                 void CacheFolderCustomCheckBoxCheckedChanged(object sender, EventArgs e)\r
420                 {\r
421                         cacheFolderTextBox.Enabled = cacheFolderCustomCheckBox.Checked;\r
422                         cacheFolderBrowseButton.Enabled = cacheFolderCustomCheckBox.Checked;\r
423                 }\r
424                 \r
425                 void CacheFolderBrowseButtonClick(object sender, EventArgs e)\r
426                 {\r
427                         string pwd = System.IO.Directory.GetCurrentDirectory();\r
428                         FolderBrowserDialog fd = new FolderBrowserDialog();\r
429                         fd.Description = "キャッシュフォルダーを指定してください。";\r
430                         fd.SelectedPath = cacheFolderTextBox.Text;\r
431                         fd.ShowNewFolderButton = true;\r
432                         \r
433                         if (fd.ShowDialog(this) == DialogResult.OK) {\r
434                                 cacheFolderTextBox.Text = fd.SelectedPath;\r
435                         }\r
436                         \r
437                         System.IO.Directory.SetCurrentDirectory(pwd); // ダイアログで変わったカレントディレクトリを元に戻す\r
438                 }\r
439                 \r
440                 void CacheFolderTextBoxValidating(object sender, System.ComponentModel.CancelEventArgs e)\r
441                 {\r
442                         string folderPath = cacheFolderTextBox.Text;\r
443                         \r
444                         if (string.IsNullOrEmpty(folderPath)) {\r
445                                 errorProvider.Clear();\r
446                                 return; // special case\r
447                         } else if (! System.IO.Directory.Exists(folderPath)) {\r
448                                 errorProvider.SetError(cacheFolderTextBox, "存在しないフォルダーパスを指定しています。");\r
449                                 e.Cancel = true;\r
450                         } else {\r
451                                 errorProvider.Clear();\r
452                         }\r
453                 }\r
454                 \r
455                 void CacheFolderOpenLinkLabelLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\r
456                 {\r
457                         string folderPath;\r
458                         \r
459                         if (cacheFolderCustomCheckBox.Checked) {\r
460                                 folderPath = cacheFolderTextBox.Text;\r
461                         } else {\r
462                                 // デフォルトは AppDataFolderPath/Cache。\r
463                                 folderPath = System.IO.Path.Combine(NaGet.Env.AppDataFolderPath, "Cache");\r
464                         }\r
465                         \r
466                         if (System.IO.Directory.Exists(folderPath)) {\r
467                                 try {\r
468                                         Process.Start(folderPath);\r
469                                 } catch (Exception ex) {\r
470                                         MessageBox.Show(ex.Message, "キャッシュフォルダー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
471                                 }\r
472                         } else {\r
473                                 MessageBox.Show(string.Format("フォルダーパス\"{0}\"は存在しませんでした。", folderPath), "キャッシュフォルダー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
474                         }\r
475                 }\r
476         }\r
477 }\r