OSDN Git Service

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