OSDN Git Service

AppliStation-GUI,OptionDialogのラジオボタンとアイコンのサイズ自動調節が無効になっていたのを修正した
[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