OSDN Git Service

AppliStation-GUI,ソフトウェアの更新ボタンを常に出すように変更した。
[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 namespace AppliStation\r
10 {\r
11         /// <summary>\r
12         /// Description of PackageListViewForm.\r
13         /// </summary>\r
14         public partial class PackageListViewForm : Form\r
15         {\r
16                 protected PackageListsManager pkgListsMan = null;\r
17                 \r
18                 public PackageListViewForm()\r
19                 {\r
20                         //\r
21                         // The InitializeComponent() call is required for Windows Forms designer support.\r
22                         //\r
23                         InitializeComponent();\r
24                         \r
25                         installToolStripMenuItem.Font = new Font(installToolStripMenuItem.Font, FontStyle.Bold);\r
26                         uninstallToolStripMenuItem.Font = new Font(uninstallToolStripMenuItem.Font, FontStyle.Bold);\r
27                         \r
28                         pkgListsMan = new PackageListsManager();\r
29                         \r
30                         this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\r
31                         AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(packageListView);\r
32                         AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(packageListView, true);\r
33                 }\r
34                 \r
35                 private void ShowInfoToDetailBoxFor(Package pkg)\r
36                 {\r
37                         detailBox.Clear();\r
38                         \r
39                         detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 12);\r
40                         detailBox.SelectedText += string.Format("{0} ({1})\r\n", pkg.Name, pkg.Version);\r
41                         if (! string.IsNullOrEmpty(pkg.Tags) ) {\r
42                                 detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8);\r
43                                 detailBox.SelectedText += "タグ:";\r
44                                 foreach (string tag in pkg.Tags.Split(' ')) {\r
45                                         detailBox.AppendText(" ");\r
46                                         AppliStation.Util.NativeMethods.RichTextBox_AddTextLink(detailBox, tag);\r
47                                 }\r
48                                 detailBox.AppendText("\r\n");\r
49                         }\r
50                         if (pkg is InstalledPackage) {\r
51                                 InstalledPackage iPkg = (InstalledPackage) pkg;\r
52                                 System.Text.StringBuilder sb = new System.Text.StringBuilder();\r
53                                 if (iPkg.UninstallInfo.InstallDate != null) {\r
54                                         sb.AppendFormat("インストールした日: {0:d}  ", iPkg.UninstallInfo.InstallDate.Value);\r
55                                 }\r
56                                 if (iPkg.UninstallInfo.EstimatedSize > 0) {\r
57                                         sb.AppendFormat("サイズ: {0}  ", NaGet.Utils.FormatSize(iPkg.UninstallInfo.EstimatedSize*1024));\r
58                                 }\r
59                                 \r
60                                 if (sb.Length > 0) {\r
61                                         detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8);\r
62                                         detailBox.SelectedText += sb.ToString();\r
63                                         detailBox.SelectedText += "\r\n";\r
64                                 }\r
65                         }\r
66                         detailBox.SelectionFont = detailBox.Font;\r
67                         if (pkg.Url != null && pkg.Url.Href != null) {\r
68                                 detailBox.SelectedText += "公式サイト: ";\r
69                                 AppliStation.Util.NativeMethods.RichTextBox_AddTextLink(detailBox, pkg.Url.Href);\r
70                                 detailBox.SelectedText += "\r\n";\r
71                         }\r
72                         detailBox.SelectedText += pkg.Summary;\r
73                 }\r
74                 \r
75                 void PackageListViewSelectedIndexChanged(object sender, EventArgs e)\r
76                 {\r
77                         uint installPkgCount = 0;\r
78                         uint uninstallPkgCount = 0;\r
79                         bool installBtnEnabled, uninstallBtnEnabled;\r
80                         \r
81                         Package[] selectedPkgs = NaGet.Utils.IEnumerable2Array<Package>(GetSelectedPackages<Package>());\r
82                         foreach (Package pkg in selectedPkgs) {\r
83                                 if (pkg is InstalledPackage) {\r
84                                         uninstallPkgCount ++;\r
85                                 } else {\r
86                                         installPkgCount ++;\r
87                                 }\r
88                         }\r
89                         installBtnEnabled = (installPkgCount > 0) && (uninstallPkgCount == 0);\r
90                         uninstallBtnEnabled = (uninstallPkgCount == 1) && (installPkgCount == 0);\r
91                         \r
92                         informationToolStripDropDownButton.Visible = (selectedPkgs.Length == 1);\r
93                         uninstallToolStripButton.Visible = uninstallBtnEnabled;\r
94                         installToolStripButton.Visible = installBtnEnabled;\r
95                         \r
96                         // detailBoxのメッセージ設定\r
97                         detailBox.Clear();\r
98                         switch (selectedPkgs.Length) {\r
99                                 case 0:\r
100                                         int count = packageListView.Items.Count;\r
101                                         detailBox.Text = (count > 0) ? string.Format("{0}個のソフトがあります。", count)\r
102                                                 : "該当するソフトがありません。";\r
103                                         break;\r
104                                 case 1:\r
105                                         ShowInfoToDetailBoxFor(selectedPkgs[0]);\r
106                                         break;\r
107                                 default: // case 2 and over:\r
108                                         detailBox.Text = (installBtnEnabled)? string.Format("{0}個のソフトが選択されています。", installPkgCount) :\r
109                                                 (uninstallBtnEnabled)? string.Format("{0}個のインストール済みのソフトが選択されています。", uninstallPkgCount) :\r
110                                                 string.Format("{0}個のソフトが選択されています。\r\n(うち{1}個はインストール済み、{2}個はインストール可能)", installPkgCount+uninstallPkgCount, uninstallPkgCount, installPkgCount);\r
111                                         break;\r
112                         }\r
113                         \r
114                         try {\r
115                                 detailBox.Select(0, 0);\r
116                                 detailBox.ScrollToCaret();\r
117                         } catch (System.Runtime.InteropServices.COMException) {\r
118                                 // ScrollToCaretでこけることがある\r
119                         }\r
120                 }\r
121 \r
122                 void PackageListViewItemActivate(object sender, EventArgs e)\r
123                 {\r
124                         if (packageListView.SelectedItems.Count <= 0) {\r
125                                 return; // exit \r
126                         }\r
127                         \r
128                         foreach (ListViewItem item in packageListView.SelectedItems) {\r
129                                 Package pkg = (Package) item.Tag;\r
130                                 \r
131                                 if (pkg is InstalledPackage) {\r
132                                         UninstallToolStripButtonClick(sender, e);\r
133                                 } else {\r
134                                         InstallToolStripButtonClick(sender, e);\r
135                                 }\r
136                                 \r
137                                 break;\r
138                         }\r
139                 }\r
140                 \r
141                 private void buildInstalledDirectoryMenuItemStripChildren(InstalledPackage pkg)\r
142                 {\r
143                         //installedDirectoryStripMenuItem.BaseFolderPath = pkg.UninstallInfo.InstallLocation;\r
144                         installedDirectoryStripMenuItem.BaseFolderPath = pkg.discoverInstalledLocation();\r
145                 }\r
146                 \r
147                 #region packageListViewのSort関連\r
148                 \r
149                 AppliStation.Util.ListViewItemSortComparer packageListViewSortComparer;\r
150 \r
151                 void PackageListViewColumnClick(object sender, ColumnClickEventArgs e)\r
152                 {\r
153                         SortOrder order = SortOrder.None;\r
154                         \r
155                         if (packageListViewSortComparer == null) {\r
156                                 order = SortOrder.Ascending;\r
157                                 packageListViewSortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order);\r
158                                 packageListView.ListViewItemSorter = packageListViewSortComparer;\r
159                         } else {\r
160                                 if (packageListViewSortComparer.Column == e.Column) {\r
161                                         order = (packageListViewSortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending;\r
162                                         \r
163                                         packageListViewSortComparer.Order = order;\r
164                                 } else {\r
165                                         order = packageListViewSortComparer.Order;\r
166                                         packageListViewSortComparer.Column = e.Column;\r
167                                 }\r
168                                 \r
169                                 packageListView.Sort();\r
170                         }\r
171                         AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(packageListView, e.Column, order);\r
172                         \r
173                         // ソート対象列の色付け\r
174                         try {\r
175                                 // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL);\r
176                                 AppliStation.Util.NativeMethods.SendMessage(packageListView.Handle, 0x1000+140, (uint) e.Column, 0);\r
177                         } catch (Exception) {   \r
178                         }\r
179                 }\r
180                 \r
181                 #endregion\r
182                 \r
183                 void Form_OnLoad(object sender, EventArgs e)\r
184                 {\r
185                         packageListViewImageList.Images.Add("installed", Icon.ExtractAssociatedIcon(Application.ExecutablePath));\r
186                         \r
187                         updatePackageFilterToolStripMenuItemCheckState();\r
188                         notInstalledPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["available-new"];\r
189                         installedASPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["installed"];\r
190                         installedSysPackageFilterToolStripMenuItem.Image = packageListViewImageList.Images["sys"];\r
191                 }\r
192                 \r
193                 #region PackageFilter関連\r
194                 \r
195                 private enum PackageFilterIndex : int\r
196                 {\r
197                         All = 0,\r
198                         NotInstalled = 1,\r
199                         InstalledAS = 2,\r
200                         InstalledSys = 3,\r
201                 }\r
202                 \r
203                 private PackageFilterIndex currentPackageFilter = PackageFilterIndex.All;\r
204                 \r
205                 private PackageFilterIndex CurrentPackageFilter {\r
206                         get {\r
207                                 return currentPackageFilter;\r
208                         }\r
209                         set {\r
210                                 currentPackageFilter = value;\r
211                                 \r
212                                 updatePackageFilterToolStripMenuItemCheckState();\r
213                         }\r
214                 }\r
215                 \r
216                 private void updatePackageFilterToolStripMenuItemCheckState()\r
217                 {\r
218                         ToolStripMenuItem selected = getCheckedPackageFilterToolStripItem();\r
219                         \r
220                         foreach (ToolStripMenuItem item in packageFilterToolStripDropDownButton.DropDown.Items) {\r
221                                 item.Checked = selected == item;\r
222                         }\r
223                         \r
224                         packageFilterToolStripDropDownButton.Text = selected.Text;\r
225                         packageFilterToolStripDropDownButton.Image = selected.Image;\r
226                         packageFilterToolStripDropDownButton.ToolTipText = selected.ToolTipText;\r
227                 }\r
228                 \r
229                 private ToolStripMenuItem getCheckedPackageFilterToolStripItem()\r
230                 {\r
231                         switch (currentPackageFilter) {\r
232                                 case PackageFilterIndex.NotInstalled:\r
233                                         return notInstalledPackageFilterToolStripMenuItem;\r
234                                 case PackageFilterIndex.InstalledAS:\r
235                                         return installedASPackageFilterToolStripMenuItem;\r
236                                 case PackageFilterIndex.InstalledSys:\r
237                                         return installedSysPackageFilterToolStripMenuItem;\r
238                                 default:\r
239                                         return allPackageFilterToolStripMenuItem;\r
240                         }\r
241                 }\r
242                 \r
243                 void AnyPackageFilterToolStripMenuItemClicked(object sender, EventArgs e)\r
244                 {\r
245                         if (sender == notInstalledPackageFilterToolStripMenuItem) {\r
246                                 currentPackageFilter = PackageFilterIndex.NotInstalled;\r
247                         } else if (sender == installedASPackageFilterToolStripMenuItem) {\r
248                                 currentPackageFilter = PackageFilterIndex.InstalledAS;\r
249                         } else if (sender == installedSysPackageFilterToolStripMenuItem) {\r
250                                 currentPackageFilter = PackageFilterIndex.InstalledSys;\r
251                         } else {\r
252                                 currentPackageFilter = PackageFilterIndex.All;\r
253                         }\r
254                         \r
255                         updatePackageFilterToolStripMenuItemCheckState();\r
256                         searchTextBox.FireTextChangedTrigger();\r
257                         PackageListViewUpdate();\r
258                 }\r
259                 \r
260                 #endregion\r
261                 \r
262                 void PackageListViewUpdate()\r
263                 {\r
264                         this.packageListView.Items.Clear();\r
265                         \r
266                         if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.NotInstalled) {\r
267                                 foreach (Package pkg in pkgListsMan.AvailablePkgList.Search(searchTextBox.Text)) {\r
268                                         if (Installation.GetPreferInstallerIndex(pkg) >= 0) { // インストール可能\r
269                                                 bool notinstalled = (pkgListsMan.InstalledPkgList.GetPackageForName(pkg.Name) == null&&\r
270                                                      pkgListsMan.SystemInstalledPkgList.GetPackageForName(pkg.Name) == null);\r
271                                                 if (currentPackageFilter == PackageFilterIndex.NotInstalled && ! notinstalled) {\r
272                                                         continue; // インストール済みは次のループへ(未インストールソフト抽出時)\r
273                                                 }\r
274                                                 \r
275                                                 ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary});\r
276                                                 item.Tag = pkg;\r
277                                                 item.ToolTipText = pkg.Summary;\r
278                                                 item.ImageKey = (notinstalled)? "available-new" : "available";\r
279                 \r
280                                                 this.packageListView.Items.Add(item);\r
281                                         }\r
282                                 }\r
283                         }\r
284                         \r
285                         if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.InstalledAS) {\r
286                                 foreach (Package pkg in pkgListsMan.InstalledPkgList.Search(searchTextBox.Text)) {\r
287                                         ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary});\r
288                                         item.Tag = pkg;\r
289                                         item.ToolTipText = pkg.Summary;\r
290                                         item.ImageKey = "installed";\r
291         \r
292                                         this.packageListView.Items.Add(item);\r
293                                 }\r
294                         }\r
295                         \r
296                         if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.InstalledSys) {\r
297                                 foreach (Package pkg in pkgListsMan.SystemInstalledPkgList.Search(searchTextBox.Text)) {\r
298                                         ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary});\r
299                                         item.Tag = pkg;\r
300                                         item.ToolTipText = pkg.Summary;\r
301                                         item.ImageKey = "sys";\r
302         \r
303                                         this.packageListView.Items.Add(item);\r
304                                 }\r
305                         }\r
306                         \r
307                         PackageListViewSelectedIndexChanged(packageListView, null);\r
308                         detailBox.Refresh();\r
309                         \r
310                         //this.packageListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);\r
311                 }\r
312                 \r
313                 void DetailBoxLinkClicked(object sender, LinkClickedEventArgs e)\r
314                 {\r
315                         if (System.Text.RegularExpressions.Regex.IsMatch(e.LinkText, "^https?://")){\r
316                                 /* URLの場合はブラウザ起動 */\r
317                                 try {\r
318                                         System.Diagnostics.Process.Start(e.LinkText);\r
319                                 } catch (System.ComponentModel.Win32Exception) {\r
320                                         MessageBox.Show(string.Format("{0}を開くのに失敗しました。", e.LinkText), "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
321                                 }\r
322                         } else {\r
323                                 /* それ以外はタグとみなして検索 */\r
324                                 searchTextBox.Text = e.LinkText;\r
325                         }\r
326                 }\r
327                 \r
328                 internal void updateActionInvoke(bool downloadPackageListsFlag)\r
329                 {\r
330                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
331                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
332                                 NaGet.SubCommands.NaGetUpdate tasks = new NaGet.SubCommands.NaGetUpdate(pkgListsMan, downloadPackageListsFlag);\r
333                                 prog.SetTaskSet(tasks);\r
334                                 prog.Refresh();\r
335                                 prog.StartTaskSet();\r
336                         };\r
337                         prog.Text = "リストの更新";\r
338                         prog.ShowDialog(this);\r
339                 }\r
340                         \r
341                 void UpdateToolStripMenuItemClick(object sender, EventArgs e)\r
342                 {\r
343                         updateActionInvoke(true);\r
344                         \r
345                         UpdatePackageList();\r
346                 }\r
347                 \r
348                 void LocalupdateToolStripMenuItemClick(object sender, EventArgs e)\r
349                 {\r
350                         updateActionInvoke(false);\r
351                         \r
352                         UpdatePackageList();\r
353                 }\r
354                 \r
355                 void OptionToolStripMenuItemClick(object sender, EventArgs e)\r
356                 {\r
357                         UserPrefForm userPrefForm = new UserPrefForm();\r
358                         DialogResult result = userPrefForm.ShowDialog(this);\r
359                         \r
360                         if (result == DialogResult.OK) {\r
361                                 if (userPrefForm.IsRepositoryListSettingChanged) {\r
362                                         updateActionInvoke(true);\r
363                                         UpdatePackageList();\r
364                                 }\r
365                         }\r
366                 }\r
367                 \r
368                 #region searchTextBoxまわり\r
369                 \r
370                 void SearchTextBoxKeyPress(object sender, KeyPressEventArgs e)\r
371                 {\r
372                         switch (e.KeyChar) {\r
373                                 case (char)Keys.Enter:\r
374                                         searchTextBox.FireTextChangedTrigger();\r
375                                         break;\r
376                                 case (char)Keys.Escape:\r
377                                         searchTextBox.Text = string.Empty;\r
378                                         break;\r
379                         }\r
380                 }\r
381                 \r
382                 void SearchTextBoxTextChangedTriggerFired(object sender, EventArgs e)\r
383                 {\r
384                         PackageListViewUpdate();\r
385                 }\r
386                 \r
387                 #endregion\r
388                 \r
389                 internal void installActionInvoke(Installation[] insts)\r
390                 {\r
391                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
392                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
393                                 NaGet.SubCommands.NaGetInstall tasks = new NaGet.SubCommands.NaGetInstall(pkgListsMan, insts);\r
394                                 prog.SetTaskSet(tasks);\r
395                                 prog.Refresh();\r
396                                 prog.StartTaskSet();\r
397                         };\r
398                         prog.Text = string.Format("ソフトウェアのインストール");\r
399                         prog.ShowDialog(this);\r
400                 }\r
401                 \r
402                 void InstallToolStripButtonClick(object sender, EventArgs e)\r
403                 {\r
404                         InstallationConfirmForm confirm = new InstallationConfirmForm();\r
405                         confirm.PkgListsManager = pkgListsMan;\r
406                         confirm.Installations = Installation.ConvertInstallations( NaGet.Utils.IEnumerable2Array(GetSelectedPackages<Package>()) );\r
407                         confirm.UseRunas = confirm.GetShouldUseRunas();\r
408                         DialogResult result = confirm.ShowDialog(this);\r
409                         \r
410                         if (result == DialogResult.OK) {\r
411                                 Installation[] insts = confirm.CheckedInstallations;\r
412                                 \r
413                                 if (confirm.UseRunas) {\r
414                                         installRunasActionInvoke(insts);\r
415                                 } else {\r
416                                         installActionInvoke(insts);\r
417                                 }\r
418                                 \r
419                                 UpdatePackageList();\r
420                         }\r
421                 }\r
422                 \r
423                 public void installRunasActionInvoke(Installation[] insts)\r
424                 {\r
425                         this.setWindowEnabled(false);\r
426                         \r
427                         string tmpfileName = Path.GetTempFileName();\r
428                         try {\r
429                                 NaGet.Utils.PutSerializeObject(tmpfileName, insts);\r
430                                 \r
431                                 System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo();\r
432                                 procInfo.FileName = Application.ExecutablePath;\r
433                                 procInfo.Arguments = string.Format("--noupdate --cmd=install \"--instsref={0}\"", tmpfileName);\r
434                                 procInfo.Verb = "runas";\r
435                                 procInfo.WorkingDirectory = Environment.CurrentDirectory;\r
436                                 \r
437                                 System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo);\r
438                                 hProc.EnableRaisingEvents = true;\r
439                                 hProc.SynchronizingObject = this;\r
440                                 hProc.Exited += delegate(object sender, EventArgs e) {\r
441                                         UpdatePackageList();\r
442                                         \r
443                                         this.setWindowEnabled(true);\r
444                                         this.BringToFront();\r
445                                         \r
446                                         if (File.Exists(tmpfileName)) {\r
447                                                 File.Delete(tmpfileName);\r
448                                         }\r
449                                 };\r
450                         } catch (System.ComponentModel.Win32Exception ex) {\r
451                                 MessageBox.Show(ex.Message, "インストール", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
452                                 \r
453                                 if (File.Exists(tmpfileName)) {\r
454                                         File.Delete(tmpfileName);\r
455                                 }                               this.setWindowEnabled(true);\r
456                         }\r
457                 }\r
458                 \r
459                 internal void uninstallActionInvoke(InstalledPackage[] pkgs)\r
460                 {\r
461                         AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer();\r
462                         prog.Shown += delegate(object sender2, EventArgs e2) {\r
463                                 NaGet.SubCommands.NaGetUninstall tasks = new NaGet.SubCommands.NaGetUninstall(pkgListsMan, pkgs);\r
464                                 prog.SetTaskSet(tasks);\r
465                                 prog.Refresh();\r
466                                 prog.StartTaskSet();\r
467                         };\r
468                         prog.Text = string.Format("ソフトウェアのアンインストール");\r
469                         prog.ShowDialog(this);\r
470                 }\r
471                 \r
472                 internal void uninstallRunasActionInvoke(InstalledPackage[] pkgs)\r
473                 {                       \r
474                         this.setWindowEnabled(false);\r
475                         \r
476                         string tmpfileName = Path.GetTempFileName();\r
477                         try {\r
478                                 NaGet.Utils.PutSerializeObject(tmpfileName, pkgs);\r
479                                 \r
480                                 System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo();\r
481                                 procInfo.FileName = Application.ExecutablePath;\r
482                                 procInfo.Arguments = string.Format("--noupdate --cmd=uninstall \"--pkgsref={0}\"", tmpfileName);\r
483                                 procInfo.Verb = "runas";\r
484                                 procInfo.WorkingDirectory = Environment.CurrentDirectory;\r
485                                 \r
486                                 System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo);\r
487                                 hProc.EnableRaisingEvents = true;\r
488                                 hProc.SynchronizingObject = this;\r
489                                 hProc.Exited += delegate(object sender, EventArgs e) {\r
490                                         UpdatePackageList();\r
491                                         \r
492                                         this.setWindowEnabled(true);\r
493                                         this.BringToFront();\r
494                                         \r
495                                         if (File.Exists(tmpfileName)) {\r
496                                                 File.Delete(tmpfileName);\r
497                                         }\r
498                                 };\r
499                         } catch (System.ComponentModel.Win32Exception ex) {\r
500                                 MessageBox.Show(ex.Message, "アンインストール", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
501                                 \r
502                                 this.setWindowEnabled(true);\r
503                                 if (File.Exists(tmpfileName)) {\r
504                                         File.Delete(tmpfileName);\r
505                                 }\r
506                         }\r
507                 }\r
508                 \r
509                 void UninstallToolStripButtonClick(object sender, EventArgs e)\r
510                 {\r
511                         PackageUninstallConfirmForm confirm = new PackageUninstallConfirmForm();\r
512                         foreach (InstalledPackage pkg in GetSelectedPackages<InstalledPackage>()) {\r
513                                 confirm.UninstallPackage = pkg;\r
514                                 break;\r
515                         }\r
516                         confirm.UseRunas = confirm.GetShouldUseRunas();\r
517                         DialogResult result = confirm.ShowDialog(this);\r
518                         \r
519                         if (result == DialogResult.OK) {\r
520                                 InstalledPackage[] instPkgs = new InstalledPackage[]{confirm.UninstallPackage};\r
521                                 \r
522                                 if (confirm.UseRunas) {\r
523                                         uninstallRunasActionInvoke(instPkgs);\r
524                                 } else {\r
525                                         uninstallActionInvoke(instPkgs);\r
526                                 }\r
527                                 \r
528                                 UpdatePackageList();\r
529                         }\r
530                 }\r
531                 \r
532                 \r
533                 void WebOfficialToolStripMenuItemClick(object sender, EventArgs e)\r
534                 {\r
535                         foreach (Package pkg in GetSelectedPackages<Package>()) {\r
536                                 string linkURL = pkg.Url.Href;\r
537                                 \r
538                                 if (! (pkg == null || string.IsNullOrEmpty(linkURL))) {\r
539                                         try {\r
540                                                 System.Diagnostics.Process.Start(linkURL);\r
541                                         } catch (System.ComponentModel.Win32Exception) {\r
542                                                 MessageBox.Show(string.Format("{0}を開くのに失敗しました。", linkURL), "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
543                                         }\r
544                                 }\r
545                                 break;\r
546                         }\r
547                 }\r
548                 \r
549                 void WebGoogleSearchToolStripMenuItemClick(object sender, EventArgs e)\r
550                 {\r
551                         foreach (Package pkg in GetSelectedPackages<Package>()) {\r
552                                 string q = System.Web.HttpUtility.UrlEncode(pkg.Name, System.Text.Encoding.UTF8);\r
553                                 string googleURL = @"http://www.google.co.jp/search?q="+q;\r
554                                 \r
555                                 try {\r
556                                         System.Diagnostics.Process.Start(googleURL);\r
557                                 } catch (System.ComponentModel.Win32Exception) {\r
558                                         MessageBox.Show("Googleを開くのに失敗しました。", "ブラウザ起動エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
559                                 }\r
560 \r
561                                 break;\r
562                         }\r
563                 }\r
564                 \r
565                 void OpenInstalledDirectoryStripMenuItemClick(object sender, EventArgs e)\r
566                 {\r
567                         foreach (InstalledPackage pkg in GetSelectedPackages<InstalledPackage>()) {\r
568                                 if (pkg.Type == InstallerType.ARCHIVE || pkg.Type == InstallerType.ITSELF) {\r
569                                         System.Diagnostics.Process.Start(Path.Combine(NaGet.Env.ArchiveProgramFiles, pkg.Name));\r
570                                 } else if (Directory.Exists(pkg.discoverInstalledLocation())) {\r
571                                         System.Diagnostics.Process.Start(pkg.discoverInstalledLocation());\r
572                                 }\r
573 \r
574                                 break;\r
575                         }\r
576                 }\r
577                 \r
578                 \r
579                 void PropertiesToolStripMenuItemClick(object sender, EventArgs e)\r
580                 {\r
581                         foreach (Package pkg in GetSelectedPackages<Package>()) {\r
582                                 PackageInfoForm form = new PackageInfoForm();\r
583                                 form.SelectedObject = pkg;\r
584                                 form.Text = string.Format("{0}({1})のプロパティ", pkg.Name, pkg.Version);\r
585                                 \r
586                                 form.ShowDialog(this);\r
587 \r
588                                 break;\r
589                         }\r
590                 }\r
591                 \r
592                 void PackageListContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)\r
593                 {\r
594                         // コンテクストメニューから開かれなかった場合はインストール/アンインストールは表示しない\r
595                         bool parentIsPkgListView = (packageListContextMenuStrip.SourceControl == packageListView);\r
596                         // メニューアイテムのインストール/アンインストールの表示はツールストリップに同じ\r
597                         installToolStripMenuItem.Visible = parentIsPkgListView && installToolStripButton.Visible;\r
598                         uninstallToolStripMenuItem.Visible = parentIsPkgListView && uninstallToolStripButton.Visible;\r
599                         \r
600                         // インストールもアンインストールもできない状態ならば、メニューを表示しない\r
601                         if (! (installToolStripButton.Visible || uninstallToolStripButton.Visible)) {\r
602                                 e.Cancel = true;\r
603                                 return;\r
604                         }\r
605                         \r
606                         // 選択パッケージが1つのとき\r
607                         bool selectionIsOnlyOne = packageListView.SelectedItems.Count == 1;\r
608                         if (selectionIsOnlyOne) {\r
609                                 Package pkg = GetSelectedPackage<Package>();\r
610                                 bool isInstalledPackage = pkg is InstalledPackage;\r
611                                 \r
612                                 webResourcesToolStripMenuItem.Text = string.Format(\r
613                                         webResourcesToolStripMenuItem.Tag.ToString(),\r
614                                         pkg.Name.Replace("&", "&&")); // pkg.Nameに&が含まれているときはエンコード\r
615                                 webOfficialToolStripMenuItem.Enabled = ! (pkg.Url == null || string.IsNullOrEmpty(pkg.Url.Href));\r
616                                 // webGoogleSearchToolStripMenuItem always active.\r
617                                 \r
618                                 if (isInstalledPackage) {\r
619                                         bool installedDirectoryStripMenuItemVisible = \r
620                                                 (pkg.Type == InstallerType.ARCHIVE) ||\r
621                                                 (pkg.Type == InstallerType.ITSELF) ||\r
622                                                 Directory.Exists(((InstalledPackage) pkg).discoverInstalledLocation());\r
623                                         \r
624                                         installedDirectoryStripMenuItem.Visible = installedDirectoryStripMenuItemVisible;\r
625                                         if (installedDirectoryStripMenuItemVisible) {\r
626                                                 buildInstalledDirectoryMenuItemStripChildren((InstalledPackage) pkg);\r
627                                         }\r
628                                 }\r
629                         }\r
630                         \r
631                         packageListContextMenuStripSeparator.Visible = parentIsPkgListView && selectionIsOnlyOne;\r
632                         webResourcesToolStripMenuItem.Visible = selectionIsOnlyOne;\r
633                         if (! selectionIsOnlyOne) installedDirectoryStripMenuItem.Visible = false;\r
634                         propertiesToolStripMenuItem.Visible = selectionIsOnlyOne;\r
635                 }\r
636                 \r
637                 private IEnumerable<Package> getUpdatedPackages(PackageList<InstalledPackage> installedPkgList, PackageList<Package> avaiablePkgList, IComparer<string> verComp)\r
638                 {\r
639                         foreach (InstalledPackage pkg in installedPkgList) {\r
640                                 Package avaiablePkg = avaiablePkgList.GetPackageForName(pkg.Name);\r
641                                 \r
642                                 if (avaiablePkg != null) {\r
643                                         if (verComp.Compare(pkg.Version, avaiablePkg.Version) < 0 &&\r
644                                             installedPkgList.GetPackageForPackage(pkg.Name, avaiablePkg.Version) == null) {\r
645                                                 \r
646                                                 yield return avaiablePkg;\r
647                                         }\r
648                                 }\r
649                         }\r
650                 }\r
651                 \r
652                 void UpgradeToolStripButtonClick(object sender, EventArgs e)\r
653                 {\r
654                         List<Package> pkgs;\r
655                         VersionComparetor verComp = new VersionComparetor();\r
656                         PackageList<Package> avaiablePackageList = pkgListsMan.AvailablePkgList;\r
657                         \r
658                         pkgs = NaGet.Utils.MeargeList(\r
659                                 getUpdatedPackages(pkgListsMan.InstalledPkgList, avaiablePackageList, verComp),\r
660                                 getUpdatedPackages(pkgListsMan.SystemInstalledPkgList, avaiablePackageList, verComp)\r
661                         );\r
662                         \r
663                         if (pkgs.Count <= 0) {\r
664                                 MessageBox.Show(this, "更新されたソフトはありません", "ソフトの更新");\r
665                                 return;\r
666                         }\r
667                         \r
668                         InstallationConfirmForm confirm = new InstallationConfirmForm();\r
669                         confirm.PkgListsManager = pkgListsMan;\r
670                         confirm.Installations = Installation.ConvertInstallations(pkgs.ToArray());\r
671                         DialogResult result = confirm.ShowDialog(this);\r
672                         \r
673                         if (result == DialogResult.OK) {\r
674                                 Installation[] insts = confirm.CheckedInstallations;\r
675                                 \r
676                                 if (confirm.UseRunas) {\r
677                                         installRunasActionInvoke(insts);\r
678                                 } else {\r
679                                         installActionInvoke(insts);\r
680                                 }\r
681                                 \r
682                                 UpdatePackageList();\r
683                         }\r
684                 }\r
685                 \r
686                 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
687                 {\r
688                         if ((int)keyData == (int)Keys.Control + (int)Keys.E) {\r
689                                 searchTextBox.SelectAll();\r
690                                 searchTextBox.Focus();\r
691                                 return true;\r
692                         }\r
693                         \r
694                         return base.ProcessCmdKey(ref msg, keyData);\r
695                 }\r
696                 \r
697                 public void UpdatePackageList()\r
698                 {\r
699                         pkgListsMan.LoadPackageLists();\r
700                         this.PackageListViewUpdate();\r
701                 }\r
702                 \r
703                 /// <summary>\r
704                 /// インストールするよう選択されたパッケージの配列\r
705                 /// </summary>\r
706                 public IEnumerable<TPackage> GetSelectedPackages<TPackage>() where TPackage : Package\r
707                 {\r
708                         foreach (ListViewItem item in packageListView.SelectedItems) {\r
709                                 yield return (TPackage) item.Tag;\r
710                         }\r
711                 }\r
712                 \r
713                 /// <summary>\r
714                 /// インストールするよう選択されたパッケージをひとつ返す。\r
715                 /// </summary>\r
716                 /// <returns>選択されたパッケージ(選択されていないときはnull)</returns>\r
717                 public TPackage GetSelectedPackage<TPackage>() where TPackage : Package\r
718                 {\r
719                         foreach (ListViewItem item in packageListView.SelectedItems) {\r
720                                 return (TPackage) item.Tag;\r
721                         }\r
722                         return null;\r
723                 }\r
724                 \r
725                 /// <summary>\r
726                 /// 自ウィンドウの有効無効(Enabled)を(必要あればInvokeして)実行する \r
727                 /// </summary>\r
728                 /// <param name="enabled">有効か否か。Enabledの値に入れられる</param>\r
729                 private void setWindowEnabled(bool enabled)\r
730                 {\r
731                         MethodInvoker process = (MethodInvoker) delegate() {\r
732                                 this.Enabled = enabled;\r
733                         };\r
734                         \r
735                         if (InvokeRequired) {\r
736                                 Invoke(process);\r
737                         } else {\r
738                                 process.Invoke();\r
739                         }\r
740                 }\r
741         }\r
742 \r
743 }\r