OSDN Git Service

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