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
}
}