OSDN Git Service

na-get-lib, a4ab378a911e444c1d35e49e4de87bc1ea86755b でのミスを修正。
[applistation/AppliStation.git] / AppliStation / PackageListView.cs
1 using System;\r
2 using System.Drawing;\r
3 using System.Windows.Forms;\r
4 using System.Collections.Generic;\r
5 using System.ComponentModel;\r
6 using NaGet.Packages;\r
7 using NaGet.Packages.Install;\r
8 using AppliStation.PackageInfo;\r
9 \r
10 namespace AppliStation\r
11 {\r
12         /// <summary>\r
13         /// PackageListViewの表示フィルタ\r
14         /// </summary>\r
15         [Flags]\r
16         public enum PackageListViewPkgTypeFilter\r
17         {\r
18                 None = 0,\r
19                 NotInstalled = 1,\r
20                 InstalledAS = 2,\r
21                 InstalledSys = 4,\r
22                 All = NotInstalled | InstalledAS | InstalledSys\r
23         }\r
24         \r
25         public class PackageListView : ListView\r
26         {\r
27 \r
28                 PackageListsManager pkgListMan = null;\r
29                 \r
30                 PackageListViewPkgTypeFilter filteringType = PackageListViewPkgTypeFilter.All;\r
31                 \r
32                 string filteringKeyword = null;\r
33                 \r
34                 AppliStation.Util.ListViewItemSortComparer sortComparer;\r
35                 \r
36                 [Category("Action")]\r
37                 public event EventHandler FilterUpdated;\r
38                 \r
39                 public PackageListView()\r
40                 {\r
41                         ListViewItemSorter = sortComparer = new AppliStation.Util.ListViewItemSortComparer();\r
42                 }\r
43                 \r
44                 /// <summary>\r
45                 /// パッケージリストのデータを設定・取得する。\r
46                 /// </summary>\r
47                 [Category("Behavior")]\r
48                 [DefaultValue(null)]\r
49                 public PackageListsManager Data\r
50                 {\r
51                         get {   return this.pkgListMan; }\r
52                         set {\r
53                                 this.pkgListMan = value;\r
54                                 \r
55                                 if (this.Visible) {\r
56                                         UpdateItems();\r
57                                 }\r
58                         }\r
59                 }\r
60                 \r
61                 /// <summary>\r
62                 /// 表示パッケージ種類フィルタを設定・取得する。\r
63                 /// </summary>\r
64                 [Category("Behavior")]\r
65                 [DefaultValue(PackageListViewPkgTypeFilter.All)]\r
66                 public PackageListViewPkgTypeFilter FilteringType {\r
67                         get { return filteringType; }\r
68                         set {\r
69                                 if (filteringType != value) {\r
70                                         filteringType = value;\r
71                                         \r
72                                         if (this.Visible) {\r
73                                                 UpdateItems();\r
74                                         }\r
75                                         \r
76                                         OnFilterUpdated(new EventArgs());\r
77                                 }\r
78                         }\r
79                 }\r
80                 \r
81                 /// <summary>\r
82                 /// 表示の際のフィルタリングキーワード\r
83                 /// </summary>\r
84                 [Category("Behavior")]\r
85                 [DefaultValue(typeof(string), null)]\r
86                 public string FilteringKeyword {\r
87                         get { return filteringKeyword; }\r
88                         set {\r
89                                 if (filteringKeyword != value) {\r
90                                         filteringKeyword = value;\r
91                                         \r
92                                         if (this.Visible) {\r
93                                                 UpdateItems();\r
94                                         }\r
95                                         \r
96                                         OnFilterUpdated(new EventArgs());\r
97                                 }\r
98                         }\r
99                 }\r
100                                 \r
101                 /// <summary>\r
102                 /// 選択されたパッケージを1つ返す\r
103                 /// </summary>\r
104                 public Package SelectedPackage {\r
105                         get {\r
106                                 if (SelectedItems.Count > 0) {\r
107                                         return (Package) (SelectedItems[0].Tag);\r
108                                 } else {\r
109                                         return null;\r
110                                 }\r
111                         }\r
112                 }\r
113                 \r
114                 /// <summary>\r
115                 /// 選択されたパッケージをイテレータとして返す\r
116                 /// </summary>\r
117                 public IEnumerable<Package> SelectedPackages {\r
118                         get {\r
119                                 foreach (ListViewItem item in SelectedItems) {\r
120                                         yield return (Package) item.Tag;\r
121                                 }\r
122                         }\r
123                 }\r
124                 \r
125                 #region データ領域作成メソッド群\r
126                 \r
127                 private ListViewItem createListViewItemForPackage(Package pkg, ImageCategory imageKey)\r
128                 {\r
129                         string[] labels = new string[this.Columns.Count];\r
130                         foreach (ColumnHeader header in this.Columns) {\r
131                                 string tag = header.Tag as string;\r
132                                 \r
133                                 if (tag == "Name")                              labels[header.Index] = pkg.Name;\r
134                                 if (tag == "Version")                   labels[header.Index] = pkg.Version;\r
135                                 if (tag == "Summary")                   labels[header.Index] = pkg.Summary;\r
136                                 if (tag == "PackageListName")   labels[header.Index] = pkg.PackageListName;\r
137                                 if (tag == "License")                   labels[header.Index] = PackageDescripter.GetLicenseValueLabel(pkg);\r
138                                 if (tag == "InstallDate") {\r
139                                         InstalledPackage instPkg = pkg as InstalledPackage;\r
140                                         if (instPkg != null && instPkg.UninstallInfo.InstallDate.HasValue) {\r
141                                                 labels[header.Index] = instPkg.UninstallInfo.InstallDate.Value.ToShortDateString();\r
142                                         }\r
143                                 }\r
144                         }\r
145                         \r
146                         ListViewItem item = new ListViewItem(labels);\r
147                         item.Tag = pkg;\r
148                         item.ToolTipText = pkg.Summary;\r
149                         item.ImageKey = ImageCategory_ToString(imageKey);\r
150                         \r
151                         return item;\r
152                 }\r
153                 \r
154                 public void UpdateItems()\r
155                 {\r
156                         string ImageKeyAvailable = ImageCategory_ToString(ImageCategory.Available);\r
157                         string ImageKeyAvailableNew = ImageCategory_ToString(ImageCategory.AvailableNew);\r
158                         string ImageKeyInstalled = ImageCategory_ToString(ImageCategory.Installed);\r
159                         string ImageKeySystem = ImageCategory_ToString(ImageCategory.System);\r
160                         string keyword = filteringKeyword ?? string.Empty;\r
161                         \r
162                         this.BeginUpdate();\r
163                         this.Items.Clear();\r
164                         \r
165                         // ソフトリストの中身のパッケージ\r
166                         if ((filteringType & PackageListViewPkgTypeFilter.NotInstalled) != 0) {\r
167                                 foreach (Package pkg in pkgListMan.AvailablePkgList.Search(keyword)) {\r
168                                         if (Installation.IsInstallablePackage(pkg)) { // インストール可能\r
169                                                 bool isInstalledAS = (pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) != null);\r
170                                                 bool isInstalledSys = (pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name) != null);\r
171                                                 \r
172                                                 // インストールされていて、インストール済みソフトを表示しないならば、次のループへ\r
173                                                 if ((((filteringType & PackageListViewPkgTypeFilter.InstalledAS) == 0) && isInstalledAS) ||\r
174                                                     (((filteringType & PackageListViewPkgTypeFilter.InstalledSys) == 0) && isInstalledSys)) {\r
175                                                         continue;\r
176                                                 }\r
177                                                 \r
178                                                 ImageCategory cat = (isInstalledAS || isInstalledSys)? ImageCategory.Available : ImageCategory.AvailableNew;\r
179                                                 Items.Add(createListViewItemForPackage(pkg, cat));\r
180                                         }\r
181                                 }\r
182                         }\r
183                         \r
184                         // AppliStationにインストール済みのパッケージ\r
185                         if ((filteringType & PackageListViewPkgTypeFilter.InstalledAS) != 0) {\r
186                                 foreach (Package pkg in pkgListMan.InstalledPkgList.Search(keyword)) {\r
187                                         Items.Add(createListViewItemForPackage(pkg, ImageCategory.Installed));\r
188                                 }\r
189                         }\r
190                         \r
191                         // PCにインストール済みのパッケージ\r
192                         if ((filteringType & PackageListViewPkgTypeFilter.InstalledSys) != 0) {\r
193                                 foreach (Package pkg in pkgListMan.SystemInstalledPkgList.Search(keyword)) {\r
194                                         Items.Add(createListViewItemForPackage(pkg, ImageCategory.System));\r
195                                 }\r
196                         }\r
197                         \r
198                         this.EndUpdate();\r
199                         \r
200                         this.Refresh();\r
201                 }\r
202                 \r
203                 protected enum ImageCategory {\r
204                         Available,\r
205                         AvailableNew,\r
206                         Installed,\r
207                         System,\r
208                 };\r
209                 \r
210                 protected static string ImageCategory_ToString(ImageCategory cat)\r
211                 {\r
212                         switch (cat) {\r
213                         case ImageCategory.Available:           return "available";\r
214                         case ImageCategory.AvailableNew:        return "available-new";\r
215                         case ImageCategory.Installed:           return "installed";\r
216                         case ImageCategory.System:                      return "sys";\r
217                         default:                                                        return string.Empty;\r
218                         }\r
219                 }\r
220                 \r
221                 #endregion\r
222                 \r
223                 protected virtual void OnFilterUpdated(EventArgs e)\r
224                 {\r
225                         if (FilterUpdated != null) {\r
226                                 FilterUpdated(this, e);\r
227                         }\r
228                 }\r
229                 \r
230                 #region Sort関連\r
231                 \r
232                 /// <summary>\r
233                 /// 選択しているコラムを設定あるいは取得を行う。\r
234                 /// </summary>\r
235                 public ColumnHeader SortColumn {\r
236                         get {\r
237                                 return sortComparer.Column;\r
238                         }\r
239                         set {\r
240                                 sortColumn(value);\r
241                         }\r
242                 }\r
243                 \r
244                 protected void sortColumn(ColumnHeader column)\r
245                 {\r
246                         int columnIndex = (column != null)? column.Index : -1;\r
247                         SortOrder order = SortOrder.None;\r
248                         \r
249                         if (columnIndex < 0) {\r
250                                 sortComparer.Order = order = SortOrder.None;\r
251                         } else if (sortComparer.ColumnIndex == columnIndex) {\r
252                                 order = (sortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending;\r
253                                         \r
254                                 sortComparer.Order = order;\r
255                         } else {\r
256                                 order = SortOrder.Ascending;\r
257                                 sortComparer.Column = column;\r
258                         }\r
259                         Sort();\r
260                         \r
261                         AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(this, columnIndex, order);\r
262                         \r
263                         // ソート対象列の色付け\r
264                         try {\r
265                                 // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, columnIndex, NULL);\r
266                                 AppliStation.Util.NativeMethods.SendMessage(this.Handle, 0x1000+140, new IntPtr(columnIndex), IntPtr.Zero);\r
267                         } catch (Exception) {   \r
268                         }\r
269                 }\r
270                 \r
271                 protected override void OnColumnClick(ColumnClickEventArgs e)\r
272                 {\r
273                         if (this.HeaderStyle == ColumnHeaderStyle.Clickable) {\r
274                                 sortColumn(this.Columns[e.Column]);\r
275                         }\r
276                         \r
277                         base.OnColumnClick(e);\r
278                 }\r
279                 \r
280                 #endregion\r
281         }\r
282 }\r