using System; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; using System.ComponentModel; using NaGet.Packages; using NaGet.Packages.Install; using AppliStation.PackageInfo; 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; AppliStation.Util.ListViewItemSortComparer sortComparer; [Category("Action")] public event EventHandler FilterUpdated; public PackageListView() { ListViewItemSorter = sortComparer = new AppliStation.Util.ListViewItemSortComparer(); } /// /// パッケージリストのデータを設定・取得する。 /// [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 ListViewItem createListViewItemForPackage(Package pkg, ImageCategory imageKey) { string[] labels = new string[this.Columns.Count]; foreach (ColumnHeader header in this.Columns) { string tag = header.Tag as string; if (tag == "Name") labels[header.Index] = pkg.Name; if (tag == "Version") labels[header.Index] = pkg.Version; if (tag == "Summary") labels[header.Index] = pkg.Summary; if (tag == "PackageListName") labels[header.Index] = pkg.PackageListName; if (tag == "License") labels[header.Index] = PackageDescripter.GetLicenseValueLabel(pkg); if (tag == "InstallDate") { InstalledPackage instPkg = pkg as InstalledPackage; if (instPkg != null && instPkg.UninstallInfo.InstallDate.HasValue) { labels[header.Index] = instPkg.UninstallInfo.InstallDate.Value.ToShortDateString(); } } } 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.BeginUpdate(); this.Items.Clear(); // ソフトリストの中身のパッケージ if ((filteringType & PackageListViewPkgTypeFilter.NotInstalled) != 0) { foreach (Package pkg in pkgListMan.AvailablePkgList.Search(keyword)) { if (Installation.IsInstallablePackage(pkg)) { // インストール可能 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.EndUpdate(); 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関連 /// /// 選択しているコラムを設定あるいは取得を行う。 /// public ColumnHeader SortColumn { get { return sortComparer.Column; } set { sortColumn(value); } } protected void sortColumn(ColumnHeader column) { int columnIndex = (column != null)? column.Index : -1; SortOrder order = SortOrder.None; if (columnIndex < 0) { sortComparer.Order = order = SortOrder.None; } else if (sortComparer.ColumnIndex == columnIndex) { order = (sortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending; sortComparer.Order = order; } else { order = SortOrder.Ascending; sortComparer.Column = column; } Sort(); AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(this, columnIndex, order); // ソート対象列の色付け try { // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, columnIndex, NULL); AppliStation.Util.NativeMethods.SendMessage(this.Handle, 0x1000+140, new IntPtr(columnIndex), IntPtr.Zero); } catch (Exception) { } } protected override void OnColumnClick(ColumnClickEventArgs e) { if (this.HeaderStyle == ColumnHeaderStyle.Clickable) { sortColumn(this.Columns[e.Column]); } base.OnColumnClick(e); } #endregion } }