OSDN Git Service

na-get-lib,ファイルダウンロードで attachment;filename= のようにセミコロン後にスペースがない場合の対応
[applistation/AppliStation.git] / AppliStation / PackageListViewForm.cs
1 using System;\r
2 using System.Drawing;\r
3 using System.Windows.Forms;\r
4 using NaGet.Packages;\r
5 using NaGet.Packages.Install;\r
6 using System.IO;\r
7 using System.Collections.Generic;\r
8 \r
9 using AppliStation.PackageInfo;\r
10 \r
11 namespace AppliStation\r
12 {\r
13         /// <summary>\r
14         /// Description of PackageListViewForm.\r
15         /// </summary>\r
16         public partial class PackageListViewForm : Form\r
17         {\r
18                 private PackageListsManager pkgListsMan = null;\r
19                 \r
20                 public PackageListViewForm()\r
21                 {\r
22                         //\r
23                         // The InitializeComponent() call is required for Windows Forms designer support.\r
24                         //\r
25                         InitializeComponent();\r
26                         \r
27                         installToolStripMenuItem.Font = new Font(installToolStripMenuItem.Font, FontStyle.Bold);\r
28                         uninstallToolStripMenuItem.Font = new Font(uninstallToolStripMenuItem.Font, FontStyle.Bold);\r
29                         \r
30                         pkgListsMan = new PackageListsManager();\r
31                         packageListView.Data = pkgListsMan;\r
32                         \r
33                         this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\r
34                         AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(packageListView);\r
35                         AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(packageListView, true);\r
36                 }\r
37                 \r
38                 private void ShowInfoToDetailBoxFor(Package pkg)\r
39                 {\r
40                         detailBox.Clear();\r
41                         \r
42                         detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 12);\r
43                         detailBox.SelectedText += string.Format("{0} ({1})\r\n", pkg.Name, pkg.Version);\r
44                         if (! string.IsNullOrEmpty(pkg.Tags) ) {\r
45                                 detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8);\r
46                                 detailBox.SelectedText += "タグ:";\r
47                                 foreach (string tag in pkg.Tags.Split(' ')) {\r
48                                         detailBox.AppendText(" ");\r
49                                         AppliStation.Util.NativeMethods.RichTextBox_AddTextLink(detailBox, tag);\r
50                                 }\r
51                                 detailBox.AppendText("\r\n");\r
52                         }\r
53                         \r
54                         // インストール済みパッケージの場合\r
55                         InstalledPackage iPkg = pkg as InstalledPackage;\r
56                         if (iPkg != null) {\r
57                                 System.Text.StringBuilder sb = new System.Text.StringBuilder();\r
58                                 if (iPkg.UninstallInfo.InstallDate != null) {\r
59                                         sb.AppendFormat("インストールした日: {0:d}  ", iPkg.UninstallInfo.InstallDate.Value);\r
60                                 }\r
61                                 if (iPkg.UninstallInfo.EstimatedSize > 0) {\r
62                                         sb.AppendFormat("サイズ: {0}  ", NaGet.Utils.FormatSize(iPkg.UninstallInfo.EstimatedSize*1024));\r
63                                 }\r
64                                 \r
65                                 if (sb.Length > 0) {\r
66                                         detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8);\r
67                                         detailBox.SelectedText += sb.ToString();\r
68                                         detailBox.SelectedText += "\r\n";\r
69                                 }\r
70                         }\r
71                         detailBox.SelectionFont = detailBox.Font;\r
72                         if (pkg.Url != null && pkg.Url.Href != null) {\r
73                                 detailBox.SelectedText += "公式サイト: ";\r
74                                 AppliStation.Util.NativeMethods.RichTextBox_AddTextLink(detailBox, pkg.Url.Href);\r
75                                 detailBox.SelectedText += "\r\n";\r
76                         }\r
77                         detailBox.SelectedText += pkg.Summary;\r
78                 }\r
79                 \r
80                 void PackageListViewSelectedIndexChanged(object sender, EventArgs e)\r
81                 {\r
82                         updateSelectedPackages();\r
83                 }\r
84                 \r
85                 private void updateSelectedPackages()\r
86                 {\r
87                         uint installPkgCount = 0;\r
88                         uint uninstallPkgCount = 0;\r
89                         bool installBtnEnabled, uninstallBtnEnabled;\r
90                         \r
91                         foreach (Package pkg in packageListView.SelectedPackages) {\r
92                                 if (pkg is InstalledPackage) {\r
93                                         uninstallPkgCount ++;\r
94                                 } else {\r
95                                         installPkgCount ++;\r
96                                 }\r
97                         }\r
98                         \r
99                         uint pkgCount = installPkgCount + uninstallPkgCount;\r
100                         installBtnEnabled = (installPkgCount > 0) && (uninstallPkgCount == 0);\r
101                         uninstallBtnEnabled = (uninstallPkgCount == 1) && (installPkgCount == 0);\r
102                         \r
103                         // ToolStrip\r
104                         informationToolStripDropDownButton.Visible = (pkgCount == 1);\r
105                         uninstallToolStripButton.Visible = uninstallBtnEnabled;\r
106                         installToolStripButton.Visible = installBtnEnabled;\r
107                         // MenuStrip\r
108                         webResourceToolStripMenuItem.Visible = (pkgCount == 1);\r
109                         uninstallToolStripMenuItem.Visible = uninstallBtnEnabled;\r
110                         installToolStripMenuItem.Visible = installBtnEnabled;\r
111                         downloadToolStripMenuItem.Visible = (pkgCount > 0);\r
112                         \r
113                         // detailBoxのメッセージ設定\r
114                         switch (pkgCount) {\r
115                                 case 0:\r
116                                         int count = packageListView.Items.Count;\r
117                                         detailBox.Clear();\r
118                                         detailBox.Text = (count > 0) ? string.Format("{0}個のソフトがあります。", count)\r
119                                                 : "該当するソフトがありません。";\r
120                                         break;\r
121                                 case 1:\r
122                                         ShowInfoToDetailBoxFor(packageListView.SelectedPackage);\r
123                                         break;\r
124                                 default: // case 2 and over:\r
125                                         detailBox.Clear();\r
126                                         detailBox.Text = (installBtnEnabled)? string.Format("{0}個のソフトが選択されています。", installPkgCount) :\r
127                                                 (uninstallBtnEnabled)? string.Format("{0}個のインストール済みのソフトが選択されています。", uninstallPkgCount) :\r
128                                                 string.Format("{0}個のソフトが選択されています。\r\n(うち{1}個はインストール済み、{2}個はインストール可能)", pkgCount, uninstallPkgCount, installPkgCount);\r
129                                         break;\r
130                         }\r
131                         \r
132                         try {\r
133                                 detailBox.Select(0, 0);\r
134                                 detailBox.ScrollToCaret();\r
135                         } catch (System.Runtime.InteropServices.COMException) {\r
136                                 // ScrollToCaretでこけることがある\r
137                         }\r
138                 }\r
139 \r
140                 void PackageListViewItemActivate(object sender, EventArgs e)\r
141                 {\r
142                         Package pkg = packageListView.SelectedPackage;\r
143                         \r
144                         if (pkg != null) {\r
145                                 if (pkg is InstalledPackage) {\r
146                                         UninstallToolStripButtonClick(sender, e);\r
147                                 } else {\r
148                                         InstallToolStripButtonClick(sender, e);\r
149                                 }\r
150                         }\r
151                 }\r
152                 \r
153                 void Form_OnLoad(object sender, EventArgs e)\r
154                 {\r
155                         packageListViewImageList.Images.Add("installed", Icon.ExtractAssociatedIcon(Application.ExecutablePath));\r
156                         \r
157                         updatePackageFilterToolStripMenuItemCheckState();\r
158                         notInstalledPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["available-new"];\r
159                         installedASPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["installed"];\r
160                         installedSysPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["sys"];\r
161                         \r
162                         packageListView.UpdateItems();\r
163                         updateSelectedPackages();\r
164                 }\r
165                 \r
166                 #region PackageFilter関連\r
167                 \r
168                 /// <summary>\r
169                 /// packgageFilterToolStripのリストを更新する。\r
170                 /// </summary>\r
171                 private void updatePackageFilterToolStripMenuItemCheckState()\r
172                 {\r
173                         ToolStripMenuItem selected = getCheckedPackageFilterToolStripItem();\r
174                         \r
175                         foreach (ToolStripMenuItem item in packageFilterToolStripDropDownButton.DropDown.Items) {\r
176                                 item.Checked = (selected == item);\r
177                         }\r
178                         \r
179                         packageFilterToolStripDropDownButton.Text = selected.Text;\r
180                         packageFilterToolStripDropDownButton.Image = selected.Image;\r
181                         packageFilterToolStripDropDownButton.ToolTipText = selected.ToolTipText;\r
182                 }\r
183                 \r
184                 private ToolStripMenuItem getCheckedPackageFilterToolStripItem()\r
185                 {\r
186                         switch (packageListView.FilteringType) {\r
187                                 case PackageListViewPkgTypeFilter.NotInstalled:\r
188                                         return notInstalledPackageFilterToolStripMenuItem;\r
189                                 case PackageListViewPkgTypeFilter.InstalledAS:\r
190                                         return installedASPackageFilterToolStripMenuItem;\r
191                                 case PackageListViewPkgTypeFilter.InstalledSys:\r
192                                         return installedSysPackageFilterToolStripMenuItem;\r
193                                 default:\r
194                                         return allPackageFilterToolStripMenuItem;\r
195                         }\r
196                 }\r
197                 \r
198                 void AnyPackageFilterToolStripMenuItemClicked(object sender, EventArgs e)\r
199                 {\r
200                         if (sender == notInstalledPackageFilterToolStripMenuItem) {\r
201                                 packageListView.FilteringType = PackageListViewPkgTypeFilter.NotInstalled;\r
202                         } else if (sender == installedASPackageFilterToolStripMenuItem) {\r
203                                 packageListView.FilteringType = PackageListViewPkgTypeFilter.InstalledAS;\r
204                         } else if (sender == installedSysPackageFilterToolStripMenuItem) {\r
205                                 packageListView.FilteringType = PackageListViewPkgTypeFilter.InstalledSys;\r
206                         } else {\r
207                                 packageListView.FilteringType = PackageListViewPkgTypeFilter.All;\r
208                         }\r
209                         \r
210                         updatePackageFilterToolStripMenuItemCheckState();\r
211                         searchTextBox.FireTextChangedTrigger();\r
212                 }\r
213                 \r
214                 #endregion\r
215                 \r
216                 void DetailBoxLinkClicked(object sender, LinkClickedEventArgs e)\r
217                 {\r
218                         if (System.Text.RegularExpressions.Regex.IsMatch(e.LinkText, "^https?://")){\r
219                                 /* URLの場合はブラウザ起動 */\r
220                                 try {\r
221                                         System.Diagnostics.Process.Start(e.LinkText);\r
222                                 } catch (System.ComponentModel.Win32Exception) {\r
223                                         MessageBox.Show(string.Format("{0}を開くのに失敗しました。", e.LinkText), "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
224                                 }\r
225                         } else {\r
226                                 /* それ以外はタグとみなして検索 */\r
227                                 searchTextBox.Text = e.LinkText;\r
228                         }\r
229                 }\r
230                 \r
231                 internal void updateActionInvoke(bool downloadPackageListsFlag)\r
232                 {\r
233                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
234                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
235                                 NaGet.SubCommands.NaGetUpdate2 tasks = new NaGet.SubCommands.NaGetUpdate2(pkgListsMan, downloadPackageListsFlag);\r
236                                 prog.SetTaskSet(tasks);\r
237                                 prog.Refresh();\r
238                                 prog.StartTaskSet();\r
239                         };\r
240                         prog.Text = "リストの更新";\r
241                         prog.ShowDialog(this);\r
242                 }\r
243                         \r
244                 void UpdateToolStripMenuItemClick(object sender, EventArgs e)\r
245                 {\r
246                         updateActionInvoke(true);\r
247                         \r
248                         UpdatePackageList();\r
249                 }\r
250                 \r
251                 void LocalupdateToolStripMenuItemClick(object sender, EventArgs e)\r
252                 {\r
253                         updateActionInvoke(false);\r
254                         \r
255                         UpdatePackageList();\r
256                 }\r
257                 \r
258                 void SoftCollectionFileImportToolStripMenuItemClick(object sender, EventArgs e)\r
259                 {\r
260                         string pwd = Directory.GetCurrentDirectory();\r
261                         \r
262                         OpenFileDialog fd = new OpenFileDialog();\r
263                         fd.Filter = "ソフトコレクションファイル (*.txt)|*.txt";\r
264                         fd.DefaultExt = "txt";\r
265                         fd.CheckFileExists = true;\r
266                         fd.CheckPathExists = true;\r
267                         fd.Multiselect = false;\r
268                         fd.ShowDialog();\r
269                         if (fd.FileNames.Length > 0) {\r
270                                 string filepath = Path.GetFullPath(fd.FileName);\r
271                                 Directory.SetCurrentDirectory(pwd); // ファイルダイアログで変わったカレントディレクトリを戻す\r
272                                 \r
273                                 IList<Package> pkgs;\r
274                                 IList<string> invalid;\r
275                                 \r
276                                 try {\r
277                                         PackageCollectionFileData collectionData = new PackageCollectionFileData();\r
278                                         collectionData.load(filepath);\r
279                                         collectionData.generatePackages(pkgListsMan, out pkgs, out invalid);\r
280                                         \r
281                                         if (invalid.Count > 0) {\r
282                                                 DialogResult result = MessageBox.Show("一部読み込みの失敗したパッケージがありますが続行しますか?", "インポート", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);\r
283                                                 if (result != DialogResult.OK) {\r
284                                                         return;\r
285                                                 }\r
286                                         }\r
287                                 } catch (IOException) {\r
288                                         MessageBox.Show("ファイルの読み込みに失敗しました", "インポート", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
289                                         return;\r
290                                 }\r
291                                 \r
292                                 {\r
293                                         InstallationConfirmForm confirm = new InstallationConfirmForm();\r
294                                         confirm.PkgListsManager = pkgListsMan;\r
295                                         confirm.Installations = Installation.ConvertInstallations( NaGet.Utils.IEnumerable2Array(pkgs) );\r
296                                         confirm.UseRunas = confirm.GetShouldUseRunas();\r
297                                         DialogResult result = confirm.ShowDialog(this);\r
298                                         \r
299                                         if (result == DialogResult.OK) {\r
300                                                 Installation[] insts = confirm.CheckedInstallations;\r
301                                                 \r
302                                                 if (confirm.UseRunas) {\r
303                                                         installRunasActionInvoke(insts);\r
304                                                 } else {\r
305                                                         installActionInvoke(insts);\r
306                                                 }\r
307                                                 \r
308                                                 UpdatePackageList();\r
309                                         }\r
310                                 }\r
311                         } else {\r
312                                 Directory.SetCurrentDirectory(pwd); // ファイルダイアログで変わったカレントディレクトリを戻す\r
313                         }\r
314                 }\r
315                 \r
316                 void SoftCollectionFileExportToolStripMenuItemClick(object sender, EventArgs e)\r
317                 {\r
318                         string pwd = Directory.GetCurrentDirectory();\r
319                         string[] softtargets = new string[]{\r
320                                 "PCにインストールされたソフト",\r
321                                 "AppliStation内でインストールされたソフト",\r
322                                 "インストールされたソフトすべて;PCとAppliStationにインストールされたソフトの両方"\r
323                         };\r
324                         int softtargetid = softtargets.Length - 1;\r
325                         \r
326                         {\r
327                                 AppliStation.Util.OptionDialog optdialog = AppliStation.Util.OptionDialog.createCommandSelectionDialog(\r
328                                         "ソフトコレクションファイルに出力するソフトの種類を選択してください。", "エクスポート", "エクスポートするソフト",\r
329                                         System.Drawing.SystemIcons.Question,\r
330                                         softtargets, softtargets.Length-1);\r
331                                 if (optdialog.ShowDialog(this) != DialogResult.OK) {\r
332                                         return; // canceled\r
333                                 } else if (optdialog.UserInputValue != null) {\r
334                                         softtargetid = (int) optdialog.UserInputValue;\r
335                                 }\r
336                         }\r
337                         \r
338                         SaveFileDialog fd = new SaveFileDialog();\r
339                         fd.Filter = "ソフトコレクションファイル (*.txt)|*.txt";\r
340                         fd.DefaultExt = "txt";\r
341                         fd.CheckPathExists = true;\r
342                         fd.OverwritePrompt = true;\r
343                         fd.ShowDialog();\r
344                         if (fd.FileNames.Length > 0) {\r
345                                 string filepath = Path.GetFullPath(fd.FileName);\r
346                                 Directory.SetCurrentDirectory(pwd); // ファイルダイアログで変わったカレントディレクトリを戻す\r
347                                 \r
348                                 PackageCollectionFileData collectionData = new PackageCollectionFileData();\r
349                                 \r
350                                 switch (softtargetid) {\r
351                                         case 0: // PCにインストール\r
352                                                 collectionData.loadPackages(pkgListsMan.SystemInstalledPkgList.GetEnumerator());\r
353                                                 break;\r
354                                         case 1: // AppliStation内にインストール\r
355                                                 collectionData.loadPackages(pkgListsMan.InstalledPkgList.GetEnumerator());\r
356                                                 break;\r
357                                         case 2: // すべて\r
358                                         default:\r
359                                                 collectionData.loadPackages(pkgListsMan.GetAllInstalledPackages());\r
360                                                 break;\r
361                                 }\r
362                                 \r
363                                 try {\r
364                                         collectionData.saveAs(fd.FileName);\r
365                                 } catch (UnauthorizedAccessException) {\r
366                                         if ((File.GetAttributes(fd.FileName) & FileAttributes.ReadOnly) != 0) {\r
367                                                 MessageBox.Show("読み取り専用属性が設定されています。\n別のファイルを指定してください。", "エクスポート", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
368                                         } else {\r
369                                                 MessageBox.Show("ファイルへの書き込みが許可されていません。\n別のファイルを指定してください。", "エクスポート", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
370                                         }\r
371                                         return;\r
372                                 } catch (IOException) {\r
373                                         MessageBox.Show("ファイルの書き込みに失敗しました", "エクスポート", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
374                                         return;\r
375                                 }\r
376                         } else {\r
377                                 Directory.SetCurrentDirectory(pwd); // ファイルダイアログで変わったカレントディレクトリを戻す\r
378                         }\r
379                 }\r
380                 \r
381                 void OptionToolStripMenuItemClick(object sender, EventArgs e)\r
382                 {\r
383                         UserPrefForm userPrefForm = new UserPrefForm();\r
384                         DialogResult result = userPrefForm.ShowDialog(this);\r
385                         \r
386                         if (result == DialogResult.OK) {\r
387                                 if (userPrefForm.IsRepositoryListSettingChanged) {\r
388                                         updateActionInvoke(true);\r
389                                         UpdatePackageList();\r
390                                 }\r
391                         }\r
392                 }\r
393                 \r
394                 #region searchTextBoxまわり\r
395                 \r
396                 void SearchTextBoxKeyPress(object sender, KeyPressEventArgs e)\r
397                 {\r
398                         switch (e.KeyChar) {\r
399                                 case (char)Keys.Enter:\r
400                                         searchTextBox.FireTextChangedTrigger();\r
401                                         break;\r
402                                 case (char)Keys.Escape:\r
403                                         searchTextBox.Text = string.Empty;\r
404                                         break;\r
405                         }\r
406                 }\r
407                 \r
408                 void SearchTextBoxTextChangedTriggerFired(object sender, EventArgs e)\r
409                 {\r
410                         packageListView.FilteringKeyword = searchTextBox.Text;\r
411                 }\r
412                 \r
413                 #endregion\r
414                 \r
415                 internal void installActionInvoke(Installation[] insts)\r
416                 {\r
417                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
418                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
419                                 NaGet.SubCommands.NaGetInstall2 tasks = new NaGet.SubCommands.NaGetInstall2(pkgListsMan, insts);\r
420                                 prog.SetTaskSet(tasks);\r
421                                 prog.Refresh();\r
422                                 prog.StartTaskSet();\r
423                         };\r
424                         prog.Text = string.Format("ソフトウェアのインストール");\r
425                         prog.ShowDialog(this);\r
426                 }\r
427                 \r
428                 void InstallToolStripButtonClick(object sender, EventArgs e)\r
429                 {\r
430                         InstallationConfirmForm confirm = new InstallationConfirmForm();\r
431                         confirm.PkgListsManager = pkgListsMan;\r
432                         confirm.Installations = Installation.ConvertInstallations( NaGet.Utils.IEnumerable2Array(packageListView.SelectedPackages) );\r
433                         confirm.UseRunas = confirm.GetShouldUseRunas();\r
434                         DialogResult result = confirm.ShowDialog(this);\r
435                         \r
436                         if (result == DialogResult.OK) {\r
437                                 Installation[] insts = confirm.CheckedInstallations;\r
438                                 \r
439                                 if (confirm.UseRunas) {\r
440                                         installRunasActionInvoke(insts);\r
441                                 } else {\r
442                                         installActionInvoke(insts);\r
443                                 }\r
444                                 \r
445                                 UpdatePackageList();\r
446                         }\r
447                 }\r
448                 \r
449                 public void installRunasActionInvoke(Installation[] insts)\r
450                 {\r
451                         this.setWindowEnabled(false);\r
452                         \r
453                         string tmpfileName = Path.GetTempFileName();\r
454                         try {\r
455                                 NaGet.Utils.PutSerializeObject(tmpfileName, insts);\r
456                                 \r
457                                 System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo();\r
458                                 procInfo.FileName = Application.ExecutablePath;\r
459                                 procInfo.Arguments = string.Format("--noupdate --cmd=install \"--instsref={0}\"", tmpfileName);\r
460                                 procInfo.Verb = "runas";\r
461                                 procInfo.WorkingDirectory = Environment.CurrentDirectory;\r
462                                 \r
463                                 System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo);\r
464                                 hProc.EnableRaisingEvents = true;\r
465                                 hProc.SynchronizingObject = this;\r
466                                 hProc.Exited += delegate(object sender, EventArgs e) {\r
467                                         UpdatePackageList();\r
468                                         \r
469                                         this.setWindowEnabled(true);\r
470                                         this.BringToFront();\r
471                                         \r
472                                         if (File.Exists(tmpfileName)) {\r
473                                                 File.Delete(tmpfileName);\r
474                                         }\r
475                                 };\r
476                         } catch (System.ComponentModel.Win32Exception ex) {\r
477                                 MessageBox.Show(ex.Message, "インストール", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
478                                 \r
479                                 if (File.Exists(tmpfileName)) {\r
480                                         File.Delete(tmpfileName);\r
481                                 }                               this.setWindowEnabled(true);\r
482                         }\r
483                 }\r
484                 \r
485                 internal void uninstallActionInvoke(InstalledPackage[] pkgs)\r
486                 {\r
487                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
488                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
489                                 NaGet.SubCommands.NaGetUninstall2 tasks = new NaGet.SubCommands.NaGetUninstall2(pkgListsMan, pkgs);\r
490                                 prog.SetTaskSet(tasks);\r
491                                 prog.Refresh();\r
492                                 prog.StartTaskSet();\r
493                         };\r
494                         prog.Text = string.Format("ソフトウェアのアンインストール");\r
495                         prog.ShowDialog(this);\r
496                 }\r
497                 \r
498                 internal void uninstallRunasActionInvoke(InstalledPackage[] pkgs)\r
499                 {                       \r
500                         this.setWindowEnabled(false);\r
501                         \r
502                         string tmpfileName = Path.GetTempFileName();\r
503                         try {\r
504                                 NaGet.Utils.PutSerializeObject(tmpfileName, pkgs);\r
505                                 \r
506                                 System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo();\r
507                                 procInfo.FileName = Application.ExecutablePath;\r
508                                 procInfo.Arguments = string.Format("--noupdate --cmd=uninstall \"--pkgsref={0}\"", tmpfileName);\r
509                                 procInfo.Verb = "runas";\r
510                                 procInfo.WorkingDirectory = Environment.CurrentDirectory;\r
511                                 \r
512                                 System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo);\r
513                                 hProc.EnableRaisingEvents = true;\r
514                                 hProc.SynchronizingObject = this;\r
515                                 hProc.Exited += delegate(object sender, EventArgs e) {\r
516                                         UpdatePackageList();\r
517                                         \r
518                                         this.setWindowEnabled(true);\r
519                                         this.BringToFront();\r
520                                         \r
521                                         if (File.Exists(tmpfileName)) {\r
522                                                 File.Delete(tmpfileName);\r
523                                         }\r
524                                 };\r
525                         } catch (System.ComponentModel.Win32Exception ex) {\r
526                                 MessageBox.Show(ex.Message, "アンインストール", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
527                                 \r
528                                 this.setWindowEnabled(true);\r
529                                 if (File.Exists(tmpfileName)) {\r
530                                         File.Delete(tmpfileName);\r
531                                 }\r
532                         }\r
533                 }\r
534                 \r
535                 void UninstallToolStripButtonClick(object sender, EventArgs e)\r
536                 {\r
537                         PackageUninstallConfirmForm confirm = new PackageUninstallConfirmForm();\r
538                         confirm.UninstallPackage = (InstalledPackage) packageListView.SelectedPackage;\r
539                         confirm.UseRunas = confirm.GetShouldUseRunas();\r
540                         DialogResult result = confirm.ShowDialog(this);\r
541                         \r
542                         if (result == DialogResult.OK) {\r
543                                 InstalledPackage[] instPkgs = new InstalledPackage[]{confirm.UninstallPackage};\r
544                                 \r
545                                 if (confirm.UseRunas) {\r
546                                         uninstallRunasActionInvoke(instPkgs);\r
547                                 } else {\r
548                                         uninstallActionInvoke(instPkgs);\r
549                                 }\r
550                                 \r
551                                 UpdatePackageList();\r
552                         }\r
553                 }\r
554                 \r
555                 internal void downloadActionInvoke(Installation[] pkgs)\r
556                 {\r
557                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
558                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
559                                 NaGet.SubCommands.NaGetDownloadToCache2 tasks = new NaGet.SubCommands.NaGetDownloadToCache2(pkgListsMan, pkgs);\r
560                                 prog.SetTaskSet(tasks);\r
561                                 prog.Refresh();\r
562                                 prog.StartTaskSet();\r
563                         };\r
564                         prog.Text = string.Format("キャッシュへのダウンロード");\r
565                         prog.ShowDialog(this);\r
566                 }\r
567                 \r
568                 void DownloadToolStripMenuItemClick(object sender, EventArgs e)\r
569                 {\r
570                         Installation[] insts = Installation.ConvertInstallations( NaGet.Utils.IEnumerable2Array(packageListView.SelectedPackages) );\r
571                         \r
572                         downloadActionInvoke(insts);\r
573                         \r
574                         UpdatePackageList();\r
575                 }\r
576                 \r
577                 void WebOfficialMenuItemClick(object sender, EventArgs e)\r
578                 {\r
579                         Package pkg = packageListView.SelectedPackage;\r
580                         if (pkg != null) {\r
581                                 string linkURL = pkg.Url.Href;\r
582                                 \r
583                                 if (! string.IsNullOrEmpty(linkURL)) {\r
584                                         try {\r
585                                                 System.Diagnostics.Process.Start(linkURL);\r
586                                         } catch (System.ComponentModel.Win32Exception) {\r
587                                                 MessageBox.Show(string.Format("{0}を開くのに失敗しました。", linkURL), "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
588                                         }\r
589                                 }\r
590                         }\r
591                 }\r
592                 \r
593                 void WebGoogleSearchMenuItemClick(object sender, EventArgs e)\r
594                 {\r
595                         Package pkg = packageListView.SelectedPackage;\r
596                         if (pkg != null) {\r
597                                 string q = System.Web.HttpUtility.UrlEncode(pkg.Name, System.Text.Encoding.UTF8);\r
598                                 string googleURL = @"http://www.google.co.jp/search?q="+q;\r
599                                 \r
600                                 try {\r
601                                         System.Diagnostics.Process.Start(googleURL);\r
602                                 } catch (System.ComponentModel.Win32Exception) {\r
603                                         MessageBox.Show("Googleを開くのに失敗しました。", "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
604                                 }\r
605                         }\r
606                 }\r
607                 \r
608                 void OpenInstalledDirectoryStripMenuItemClick(object sender, EventArgs e)\r
609                 {\r
610                         InstalledPackage pkg = (InstalledPackage) packageListView.SelectedPackage;\r
611                         if (pkg != null) {\r
612                                 if (pkg.Type == InstallerType.ARCHIVE || pkg.Type == InstallerType.ITSELF) {\r
613                                         System.Diagnostics.Process.Start(Path.Combine(NaGet.Env.ArchiveProgramFiles, pkg.Name));\r
614                                 } else if (Directory.Exists(pkg.DiscoverInstalledLocation())) {\r
615                                         System.Diagnostics.Process.Start(pkg.DiscoverInstalledLocation());\r
616                                 }\r
617                         }\r
618                 }\r
619                 \r
620                 \r
621                 void PropertiesCommonMenuItemClick(object sender, EventArgs e)\r
622                 {\r
623                         if (packageListView.SelectedItems.Count >= 5) {\r
624                                 string msg = string.Format("{0}個のプロパティダイアログを開こうとしています。\n継続しますか?", packageListView.SelectedItems.Count);\r
625                                 if (MessageBox.Show(msg, "プロパティ", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK) {\r
626                                         return;\r
627                                 }\r
628                         }\r
629                         \r
630                         foreach (Package pkg in packageListView.SelectedPackages) {\r
631                                 PackageInfoForm form = new PackageInfoForm();\r
632                                 form.SelectedObject = pkg;\r
633                                 form.Text = string.Format("{0}({1})のプロパティ", pkg.Name, pkg.Version);\r
634                                 \r
635                                 form.Show(this);\r
636                         }\r
637                 }\r
638                 \r
639                 private void updateLauncherMenuItem(AppliStation.Util.ToolStripPetitLauncherMenuItem launcherMenuItem)\r
640                 {\r
641                         bool selectionIsOnlyOne = packageListView.SelectedItems.Count == 1;\r
642                         \r
643                         if (selectionIsOnlyOne) {\r
644                                 Package pkg = packageListView.SelectedPackage;\r
645                                 InstalledPackage iPkg = pkg as InstalledPackage;\r
646                                 \r
647                                 // インストール済みパッケージのとき\r
648                                 if (iPkg != null) {\r
649                                         bool launcherMenuItemVisible = \r
650                                                 (pkg.Type == InstallerType.ARCHIVE) ||\r
651                                                 (pkg.Type == InstallerType.ITSELF) ||\r
652                                                 Directory.Exists(iPkg.DiscoverInstalledLocation());\r
653                                         \r
654                                         launcherMenuItem.Visible = launcherMenuItemVisible;\r
655                                         if (launcherMenuItemVisible) {\r
656                                                 launcherMenuItem.BaseFolderPath = iPkg.DiscoverInstalledLocation();\r
657                                         }\r
658                                 } else {\r
659                                         launcherMenuItem.Visible = false;\r
660                                 }\r
661                         } else {\r
662                                 launcherMenuItem.Visible = false;\r
663                         }\r
664                 }\r
665                 \r
666                 void PackageListContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)\r
667                 {\r
668                         bool selectionIsOnlyOne = packageListView.SelectedItems.Count == 1;\r
669                         bool hasSelection = packageListView.SelectedItems.Count > 0;\r
670                         \r
671                         updateSelectedPackages();\r
672                         \r
673                         // インストール先のフォルダの設定\r
674                         updateLauncherMenuItem(installedDirectoryToolStripMenuItem);\r
675                         \r
676                         if (packageListView.View == View.Details) {\r
677                                 // ヘッダ部がクリックされたとき、パッケージが選択されていないものとして扱って処理をする。\r
678                                 int headerHeight = AppliStation.Util.NativeMethods.ColumnHeader_GetSize(packageListView).Height;\r
679                                 if (packageListView.PointToClient(packageListContextMenuStrip.Location).Y < headerHeight) {\r
680                                         selectionIsOnlyOne = hasSelection = false;\r
681                                         uninstallToolStripMenuItem.Visible = false;\r
682                                         installToolStripMenuItem.Visible = false;\r
683                                         downloadToolStripMenuItem.Visible = false;\r
684                                         installedDirectoryToolStripMenuItem.Visible = false;\r
685                                 }\r
686                         }\r
687                         \r
688                         packageListContextMenuStripSeparator.Visible = selectionIsOnlyOne;\r
689                         webResourceToolStripMenuItem.Visible = selectionIsOnlyOne;\r
690                         propertiesToolStripMenuItem.Visible = hasSelection;\r
691                         columnToolStripMenuItem.Visible = (! hasSelection) && (packageListView.View == View.Details);\r
692                 }\r
693                 \r
694                 void InformationToolStripDropDownButtonDropDownOpening(object sender, EventArgs e)\r
695                 {\r
696                         bool selectionIsOnlyOne = packageListView.SelectedItems.Count == 1;\r
697                         bool hasSelection = packageListView.SelectedItems.Count > 0;\r
698                         \r
699                         // インストール先のフォルダの設定\r
700                         updateLauncherMenuItem(installedDirectoryMenuItem);\r
701                         \r
702                         webResourceMenuItem.Visible = selectionIsOnlyOne;\r
703                         propertiesMenuItem.Visible = hasSelection;\r
704                 }\r
705                 \r
706                 void WebResourceCommonContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)\r
707                 {\r
708                         Package pkg = packageListView.SelectedPackage;\r
709                         \r
710                         if (pkg != null && pkg.Url != null && !string.IsNullOrEmpty(pkg.Url.Href)) {\r
711                                 webOfficialMenuItem.Enabled = true;\r
712                                 webOfficialMenuItem.ToolTipText = pkg.Url.Href;\r
713                         } else {\r
714                                 webOfficialMenuItem.Enabled = false;\r
715                                 webOfficialMenuItem.ToolTipText = null;\r
716                         }\r
717                         \r
718                         // webGoogleSearchMenuItem always active.\r
719                 }\r
720                 \r
721                 void UpgradeToolStripButtonClick(object sender, EventArgs e)\r
722                 {\r
723                         List<Package> pkgs = new List<Package>(\r
724                                 UpgradeFinder.GetUpgradePackages(pkgListsMan)\r
725                         );\r
726                         \r
727                         if (pkgs.Count <= 0) {\r
728                                 MessageBox.Show(this, "更新されたソフトはありません", "ソフトの更新");\r
729                                 return;\r
730                         }\r
731                         \r
732                         InstallationConfirmForm confirm = new InstallationConfirmForm();\r
733                         confirm.PkgListsManager = pkgListsMan;\r
734                         confirm.Installations = Installation.ConvertInstallations(pkgs.ToArray());\r
735                         DialogResult result = confirm.ShowDialog(this);\r
736                         \r
737                         if (result == DialogResult.OK) {\r
738                                 Installation[] insts = confirm.CheckedInstallations;\r
739                                 \r
740                                 if (confirm.UseRunas) {\r
741                                         installRunasActionInvoke(insts);\r
742                                 } else {\r
743                                         installActionInvoke(insts);\r
744                                 }\r
745                                 \r
746                                 UpdatePackageList();\r
747                         }\r
748                 }\r
749                 \r
750                 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
751                 {\r
752                         if ((int)keyData == (int)Keys.Control + (int)Keys.E) {\r
753                                 searchTextBox.SelectAll();\r
754                                 searchTextBox.Focus();\r
755                                 return true;\r
756                         }\r
757                         \r
758                         return base.ProcessCmdKey(ref msg, keyData);\r
759                 }\r
760                 \r
761                 public void UpdatePackageList()\r
762                 {\r
763                         pkgListsMan.LoadPackageLists();\r
764                         packageListView.UpdateItems();\r
765                         updateSelectedPackages();\r
766                 }\r
767                 \r
768                 /// <summary>\r
769                 /// 自ウィンドウの有効無効(Enabled)を(必要あればInvokeして)実行する \r
770                 /// </summary>\r
771                 /// <param name="enabled">有効か否か。Enabledの値に入れられる</param>\r
772                 private void setWindowEnabled(bool enabled)\r
773                 {\r
774                         MethodInvoker process = (MethodInvoker) delegate() {\r
775                                 this.Enabled = enabled;\r
776                         };\r
777                         \r
778                         if (InvokeRequired) {\r
779                                 Invoke(process);\r
780                         } else {\r
781                                 process.Invoke();\r
782                         }\r
783                 }\r
784                 \r
785                 void ColumnCommonToolStripMenuItemClick(object sender, EventArgs e)\r
786                 {\r
787                         packageListView.BeginUpdate();\r
788                         ColumnHeader sortcolumn = packageListView.SortColumn;\r
789                         \r
790                         // 列の追加と削除\r
791                         foreach (ToolStripItem item in columnToolStripMenuItem.DropDownItems) {\r
792                                 ToolStripMenuItem menu = item as ToolStripMenuItem;\r
793                                 if (menu != null) {\r
794                                         bool exists = false;\r
795                                         // 列が存在しているがチェックが外れていたら削除する。\r
796                                         foreach (ColumnHeader header in packageListView.Columns) {\r
797                                                 if (header.Tag == menu.Tag) {\r
798                                                         exists = true;\r
799                                                         if (sortcolumn == header) {\r
800                                                                 packageListView.SortColumn = sortcolumn = null;\r
801                                                         }\r
802                                                         if (menu.Checked == false) {\r
803                                                                 packageListView.Columns.Remove(header);\r
804                                                         }\r
805                                                         break;\r
806                                                 }\r
807                                         }\r
808                                         \r
809                                         // 列が存在していなく、チェックがされているなら追加する。\r
810                                         if (menu.Checked && !exists) {\r
811                                                 ColumnHeader header = new ColumnHeader();\r
812                                                 header.Text = menu.Text;\r
813                                                 header.Tag = menu.Tag;\r
814                                                 packageListView.Columns.Add(header);\r
815                                         }\r
816                                 }\r
817                         }\r
818                         \r
819                         AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(packageListView, (sortcolumn != null)? sortcolumn.Index : -1, SortOrder.None);\r
820                         \r
821                         packageListView.UpdateItems();\r
822                         \r
823                         packageListView.EndUpdate();\r
824                 }\r
825         }\r
826 \r
827 }\r