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.BeginUpdate();
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.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関連
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
}
}