// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using ICSharpCode.SharpDevelop;
using ICSharpCode.AddInManager2.Model;
using NuGet;
namespace ICSharpCode.AddInManager2.ViewModel
{
///
/// Base class for view models displaying NuGet
///
public class NuGetAddInsViewModelBase : AddInsViewModelBase
{
private AddInManagerTask _task;
private IEnumerable _allPackages;
public NuGetAddInsViewModelBase()
: base()
{
}
public NuGetAddInsViewModelBase(IAddInManagerServices services)
: base(services)
{
}
///
/// Returns all the packages.
///
protected virtual IQueryable GetAllPackages()
{
return null;
}
public override void ReadPackages()
{
base.ReadPackages();
_allPackages = null;
UpdateRepositoryBeforeReadPackagesTaskStarts();
StartReadPackagesTask();
}
private void StartReadPackagesTask()
{
IsReadingPackages = true;
HasError = false;
// ClearPackages();
CancelReadPackagesTask();
CreateReadPackagesTask();
_task.Start();
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Started task");
}
protected virtual void UpdateRepositoryBeforeReadPackagesTaskStarts()
{
}
private void CancelReadPackagesTask()
{
if (_task != null)
{
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Cancelled task");
_task.Cancel();
}
}
private void CreateReadPackagesTask()
{
_task = AddInManagerTask.Create(
GetPackagesForSelectedPageResult,
OnPackagesReadForSelectedPage);
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Created task");
}
private ReadPackagesResult GetPackagesForSelectedPageResult()
{
IEnumerable packages = GetPackagesForSelectedPage();
return new ReadPackagesResult(packages, TotalItems);
}
private void OnPackagesReadForSelectedPage(AddInManagerTask task)
{
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Task has returned");
IsReadingPackages = false;
bool wasSuccessful = false;
bool wasCancelled = false;
if (task.IsFaulted)
{
SaveError(task.Exception);
}
else if (task.IsCancelled)
{
// Ignore
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Task ignored, because cancelled");
wasCancelled = true;
}
else
{
// SD.Log.Debug("[AddInManager2] NuGetAddInsViewModelBase: Task successfully finished.");
UpdatePackagesForSelectedPage(task.Result);
wasSuccessful = true;
}
base.OnPropertyChanged(null);
AddInManager.Events.OnPackageListDownloadEnded(this, new PackageListDownloadEndedEventArgs(wasSuccessful, wasCancelled));
}
private void UpdatePackagesForSelectedPage(ReadPackagesResult result)
{
PagesCollection.TotalItems = result.TotalPackages;
PagesCollection.TotalItemsOnSelectedPage = result.TotalPackagesOnPage;
UpdatePackageViewModels(result.Packages);
}
private void PagesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
StartReadPackagesTask();
base.OnPropertyChanged(null);
}
private IEnumerable GetPackagesForSelectedPage()
{
IEnumerable filteredPackages = GetFilteredPackagesBeforePagingResults();
return GetPackagesForSelectedPage(filteredPackages);
}
private IEnumerable GetFilteredPackagesBeforePagingResults()
{
if (_allPackages == null)
{
IQueryable packages = GetAllPackages();
packages = OrderPackages(packages);
packages = FilterPackagesBySearchCriteria(packages);
TotalItems = packages.Count();
_allPackages = GetFilteredPackagesBeforePagingResults(packages);
}
return _allPackages;
}
private IQueryable OrderPackages(IQueryable packages)
{
return packages
.OrderBy(package => package.Id)
.ThenBy(package => package.Version);
}
private IQueryable FilterPackagesBySearchCriteria(IQueryable packages)
{
string searchCriteria = GetSearchCriteria();
return FilterPackagesBySearchCriteria(packages, searchCriteria);
}
private IQueryable FilterPackagesByStaticFilter(IQueryable packages)
{
// Look for "SharpDevelopAddIn" tag to show only SD AddIn packages
return packages.Find(new string[] { "Tags" }, "sharpdevelopaddin");
}
private string GetSearchCriteria()
{
if (String.IsNullOrWhiteSpace(SearchTerms))
{
return null;
}
return SearchTerms;
}
protected IQueryable FilterPackagesBySearchCriteria(IQueryable packages, string searchCriteria)
{
return packages.Find(searchCriteria);
}
private IEnumerable GetPackagesForSelectedPage(IEnumerable allPackages)
{
int packagesToSkip = PagesCollection.ItemsBeforeFirstPage;
return allPackages
.Skip(packagesToSkip)
.Take(PagesCollection.PageSize);
}
///
/// Allows filtering of the packages before paging the results. Call base class method
/// to run default filtering.
///
protected virtual IEnumerable GetFilteredPackagesBeforePagingResults(IQueryable allPackages)
{
return GetBufferedPackages(allPackages)
.Where(package => ShowPrereleases || package.IsReleaseVersion())
.DistinctLast(PackageEqualityComparer.Id);
}
private IEnumerable GetBufferedPackages(IQueryable allPackages)
{
return allPackages.AsBufferedEnumerable(30);
}
protected virtual void UpdatePackageViewModels(IEnumerable packages)
{
IEnumerable currentViewModels = ConvertToAddInViewModels(packages);
UpdatePackageViewModels(currentViewModels);
}
protected IEnumerable ConvertToAddInViewModels(IEnumerable packages)
{
foreach (IPackage package in packages)
{
yield return CreateAddInViewModel(package);
}
}
protected virtual AddInPackageViewModelBase CreateAddInViewModel(IPackage package)
{
return new NuGetPackageViewModel(AddInManager, package);
}
public override int SelectedPageNumber
{
get
{
return base.SelectedPageNumber;
}
set
{
if (base.SelectedPageNumber != value)
{
base.SelectedPageNumber = value;
StartReadPackagesTask();
base.OnPropertyChanged(null);
}
}
}
}
}