using System; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; using System.ComponentModel; using NaGet.Packages; using NaGet.Packages.Install; namespace AppliStation { /// /// PackageListViewの表示フィルタ /// [Flags] public enum PackageListViewPkgTypeFilter { None = 0, NotInstalled = 1, InstalledAS = 2, InstalledSys = 4, All = NotInstalled | InstalledAS | InstalledSys } public class PackageListView : ListView { PackageListsManager pkgListMan = null; PackageListViewPkgTypeFilter filteringType = PackageListViewPkgTypeFilter.All; string filteringKeyword = null; [Category("Action")] public event EventHandler FilterUpdated; public PackageListView() { } /// /// パッケージリストのデータを設定・取得する。 /// [Category("Behavior")] [DefaultValue(null)] public PackageListsManager Data { get { return this.pkgListMan; } set { this.pkgListMan = value; if (this.Visible) { UpdateItems(); } } } /// /// 表示パッケージ種類フィルタを設定・取得する。 /// [Category("Behavior")] [DefaultValue(PackageListViewPkgTypeFilter.All)] public PackageListViewPkgTypeFilter FilteringType { get { return filteringType; } set { if (filteringType != value) { filteringType = value; if (this.Visible) { UpdateItems(); } OnFilterUpdated(new EventArgs()); } } } /// /// 表示の際のフィルタリングキーワード /// [Category("Behavior")] [DefaultValue(typeof(string), null)] public string FilteringKeyword { get { return filteringKeyword; } set { if (filteringKeyword != value) { filteringKeyword = value; if (this.Visible) { UpdateItems(); } OnFilterUpdated(new EventArgs()); } } } /// /// 選択されたパッケージを1つ返す /// public Package SelectedPackage { get { if (SelectedItems.Count > 0) { return (Package) (SelectedItems[0].Tag); } else { return null; } } } /// /// 選択されたパッケージをイテレータとして返す /// public IEnumerable SelectedPackages { get { foreach (ListViewItem item in SelectedItems) { yield return (Package) item.Tag; } } } #region データ領域作成メソッド群 private static ListViewItem createListViewItemForPackage(Package pkg, ImageCategory imageKey) { string[] labels = new string[]{ pkg.Name, pkg.Version, pkg.Summary, }; ListViewItem item = new ListViewItem(labels); item.Tag = pkg; item.ToolTipText = pkg.Summary; item.ImageKey = ImageCategory_ToString(imageKey); return item; } public void UpdateItems() { string ImageKeyAvailable = ImageCategory_ToString(ImageCategory.Available); string ImageKeyAvailableNew = ImageCategory_ToString(ImageCategory.AvailableNew); string ImageKeyInstalled = ImageCategory_ToString(ImageCategory.Installed); string ImageKeySystem = ImageCategory_ToString(ImageCategory.System); string keyword = filteringKeyword ?? string.Empty; this.Items.Clear(); // ソフトリストの中身のパッケージ if ((filteringType & PackageListViewPkgTypeFilter.NotInstalled) != 0) { foreach (Package pkg in pkgListMan.AvailablePkgList.Search(keyword)) { if (Installation.GetPreferInstallerIndex(pkg) >= 0) { // インストール可能 bool isInstalledAS = (pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) != null); bool isInstalledSys = (pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name) != null); // インストールされていて、インストール済みソフトを表示しないならば、次のループへ if ((((filteringType & PackageListViewPkgTypeFilter.InstalledAS) == 0) && isInstalledAS) || (((filteringType & PackageListViewPkgTypeFilter.InstalledSys) == 0) && isInstalledSys)) { continue; } ImageCategory cat = (isInstalledAS || isInstalledSys)? ImageCategory.Available : ImageCategory.AvailableNew; Items.Add(createListViewItemForPackage(pkg, cat)); } } } // AppliStationにインストール済みのパッケージ if ((filteringType & PackageListViewPkgTypeFilter.InstalledAS) != 0) { foreach (Package pkg in pkgListMan.InstalledPkgList.Search(keyword)) { Items.Add(createListViewItemForPackage(pkg, ImageCategory.Installed)); } } // PCにインストール済みのパッケージ if ((filteringType & PackageListViewPkgTypeFilter.InstalledSys) != 0) { foreach (Package pkg in pkgListMan.SystemInstalledPkgList.Search(keyword)) { Items.Add(createListViewItemForPackage(pkg, ImageCategory.System)); } } this.Refresh(); } protected enum ImageCategory { Available, AvailableNew, Installed, System, }; protected static string ImageCategory_ToString(ImageCategory cat) { switch (cat) { case ImageCategory.Available: return "available"; case ImageCategory.AvailableNew: return "available-new"; case ImageCategory.Installed: return "installed"; case ImageCategory.System: return "sys"; default: return string.Empty; } } #endregion protected virtual void OnFilterUpdated(EventArgs e) { if (FilterUpdated != null) { FilterUpdated(this, e); } } #region Sort関連 AppliStation.Util.ListViewItemSortComparer sortComparer; protected override void OnColumnClick(ColumnClickEventArgs e) { if (this.HeaderStyle == ColumnHeaderStyle.Clickable) { onColumnClick(e); } base.OnColumnClick(e); } private void onColumnClick(ColumnClickEventArgs e) { SortOrder order = SortOrder.None; if (sortComparer == null) { order = SortOrder.Ascending; sortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order); ListViewItemSorter = sortComparer; } else { if (sortComparer.Column == e.Column) { order = (sortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending; sortComparer.Order = order; } else { order = sortComparer.Order; sortComparer.Column = e.Column; } Sort(); } AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(this, e.Column, order); // ソート対象列の色付け try { // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL); AppliStation.Util.NativeMethods.SendMessage(this.Handle, 0x1000+140, new IntPtr(e.Column), IntPtr.Zero); } catch (Exception) { } } #endregion } }