OSDN Git Service

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