#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

365 lines
9.6 KiB

// 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.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Windows.Input;
using NuGet;
namespace ICSharpCode.PackageManagement
{
public abstract class PackagesViewModel : ViewModelBase<PackagesViewModel>, IDisposable
{
Pages pages = new Pages();
IRegisteredPackageRepositories registeredPackageRepositories;
IPackageViewModelFactory packageViewModelFactory;
ITaskFactory taskFactory;
IEnumerable<IPackage> allPackages;
ITask<PackagesForSelectedPageResult> task;
public PackagesViewModel(
IRegisteredPackageRepositories registeredPackageRepositories,
IPackageViewModelFactory packageViewModelFactory,
ITaskFactory taskFactory)
{
this.registeredPackageRepositories = registeredPackageRepositories;
this.packageViewModelFactory = packageViewModelFactory;
this.taskFactory = taskFactory;
PackageViewModels = new ObservableCollection<PackageViewModel>();
ErrorMessage = String.Empty;
CreateCommands();
}
void CreateCommands()
{
ShowNextPageCommand = new DelegateCommand(param => ShowNextPage());
ShowPreviousPageCommand = new DelegateCommand(param => ShowPreviousPage());
ShowPageCommand = new DelegateCommand(param => ExecuteShowPageCommand(param));
SearchCommand = new DelegateCommand(param => Search());
}
public ICommand ShowNextPageCommand { get; private set; }
public ICommand ShowPreviousPageCommand { get; private set; }
public ICommand ShowPageCommand { get; private set; }
public ICommand SearchCommand { get; private set; }
public void Dispose()
{
OnDispose();
IsDisposed = true;
}
protected virtual void OnDispose()
{
}
public bool IsDisposed { get; private set; }
public bool HasError { get; private set; }
public string ErrorMessage { get; private set; }
public ObservableCollection<PackageViewModel> PackageViewModels { get; set; }
public IRegisteredPackageRepositories RegisteredPackageRepositories {
get { return registeredPackageRepositories; }
}
public bool IsReadingPackages { get; private set; }
public void ReadPackages()
{
allPackages = null;
pages.SelectedPageNumber = 1;
UpdateRepositoryBeforeReadPackagesTaskStarts();
StartReadPackagesTask();
}
void StartReadPackagesTask()
{
IsReadingPackages = true;
HasError = false;
ClearPackages();
CancelReadPackagesTask();
CreateReadPackagesTask();
task.Start();
}
protected virtual void UpdateRepositoryBeforeReadPackagesTaskStarts()
{
}
void CancelReadPackagesTask()
{
if (task != null) {
task.Cancel();
}
}
void CreateReadPackagesTask()
{
task = taskFactory.CreateTask(
() => GetPackagesForSelectedPageResult(),
(result) => OnPackagesReadForSelectedPage(result));
}
PackagesForSelectedPageResult GetPackagesForSelectedPageResult()
{
IEnumerable<IPackage> packages = GetPackagesForSelectedPage();
return new PackagesForSelectedPageResult(packages, TotalItems);
}
void OnPackagesReadForSelectedPage(ITask<PackagesForSelectedPageResult> task)
{
IsReadingPackages = false;
if (task.IsFaulted) {
SaveError(task.Exception);
} else if (task.IsCancelled) {
// Ignore
} else {
UpdatePackagesForSelectedPage(task.Result);
}
base.OnPropertyChanged(null);
}
void SaveError(AggregateException ex)
{
HasError = true;
ErrorMessage = GetErrorMessage(ex);
ICSharpCode.Core.LoggingService.Debug(ex);
}
string GetErrorMessage(AggregateException ex)
{
var errorMessage = new AggregateExceptionErrorMessage(ex);
return errorMessage.ToString();
}
void UpdatePackagesForSelectedPage(PackagesForSelectedPageResult result)
{
pages.TotalItems = result.TotalPackages;
pages.TotalItemsOnSelectedPage = result.TotalPackagesOnPage;
UpdatePackageViewModels(result.Packages);
}
void PagesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
StartReadPackagesTask();
base.OnPropertyChanged(null);
}
IEnumerable<IPackage> GetPackagesForSelectedPage()
{
IEnumerable<IPackage> filteredPackages = GetFilteredPackagesBeforePagingResults();
return GetPackagesForSelectedPage(filteredPackages);
}
IEnumerable<IPackage> GetFilteredPackagesBeforePagingResults()
{
if (allPackages == null) {
IQueryable<IPackage> packages = GetPackagesFromPackageSource();
TotalItems = packages.Count();
allPackages = GetFilteredPackagesBeforePagingResults(packages);
}
return allPackages;
}
/// <summary>
/// Returns the queryable object that will be used to query the NuGet online feed.
/// </summary>
public IQueryable<IPackage> GetPackagesFromPackageSource()
{
IQueryable<IPackage> packages = GetAllPackages();
packages = OrderPackages(packages);
return FilterPackagesBySearchCriteria(packages);
}
protected virtual IQueryable<IPackage> OrderPackages(IQueryable<IPackage> packages)
{
return packages
.OrderBy(package => package.Id);
}
IQueryable<IPackage> FilterPackagesBySearchCriteria(IQueryable<IPackage> packages)
{
string searchCriteria = GetSearchCriteria();
return FilterPackagesBySearchCriteria(packages, searchCriteria);
}
string GetSearchCriteria()
{
if (String.IsNullOrWhiteSpace(SearchTerms)) {
return null;
}
return SearchTerms;
}
protected virtual IQueryable<IPackage> FilterPackagesBySearchCriteria(IQueryable<IPackage> packages, string searchCriteria)
{
return packages.Find(searchCriteria);
}
IEnumerable<IPackage> GetPackagesForSelectedPage(IEnumerable<IPackage> allPackages)
{
int packagesToSkip = pages.ItemsBeforeFirstPage;
return allPackages
.Skip(packagesToSkip)
.Take(pages.PageSize);
}
/// <summary>
/// Returns all the packages.
/// </summary>
protected virtual IQueryable<IPackage> GetAllPackages()
{
return null;
}
/// <summary>
/// Allows filtering of the packages before paging the results. Call base class method
/// to run default filtering.
/// </summary>
protected virtual IEnumerable<IPackage> GetFilteredPackagesBeforePagingResults(IQueryable<IPackage> allPackages)
{
IEnumerable<IPackage> bufferedPackages = GetBufferedPackages(allPackages);
return bufferedPackages;
}
IEnumerable<IPackage> GetBufferedPackages(IQueryable<IPackage> allPackages)
{
return allPackages.AsBufferedEnumerable(30);
}
void UpdatePackageViewModels(IEnumerable<IPackage> packages)
{
IEnumerable<PackageViewModel> currentViewModels = ConvertToPackageViewModels(packages);
UpdatePackageViewModels(currentViewModels);
}
void UpdatePackageViewModels(IEnumerable<PackageViewModel> newPackageViewModels)
{
ClearPackages();
PackageViewModels.AddRange(newPackageViewModels);
}
void ClearPackages()
{
PackageViewModels.Clear();
}
public IEnumerable<PackageViewModel> ConvertToPackageViewModels(IEnumerable<IPackage> packages)
{
foreach (IPackage package in packages) {
yield return CreatePackageViewModel(package);
}
}
PackageViewModel CreatePackageViewModel(IPackage package)
{
var repository = registeredPackageRepositories.ActiveRepository;
var packageFromRepository = new PackageFromRepository(package, repository);
return packageViewModelFactory.CreatePackageViewModel(packageFromRepository);
}
public int SelectedPageNumber {
get { return pages.SelectedPageNumber; }
set {
if (pages.SelectedPageNumber != value) {
pages.SelectedPageNumber = value;
StartReadPackagesTask();
base.OnPropertyChanged(null);
}
}
}
public int PageSize {
get { return pages.PageSize; }
set { pages.PageSize = value; }
}
public bool IsPaged {
get { return pages.IsPaged; }
}
public ObservableCollection<Page> Pages {
get { return pages; }
}
public bool HasPreviousPage {
get { return pages.HasPreviousPage; }
}
public bool HasNextPage {
get { return pages.HasNextPage; }
}
public int MaximumSelectablePages {
get { return pages.MaximumSelectablePages; }
set { pages.MaximumSelectablePages = value; }
}
public int TotalItems { get; private set; }
public void ShowNextPage()
{
SelectedPageNumber += 1;
}
public void ShowPreviousPage()
{
SelectedPageNumber -= 1;
}
void ExecuteShowPageCommand(object param)
{
int pageNumber = (int)param;
ShowPage(pageNumber);
}
public void ShowPage(int pageNumber)
{
SelectedPageNumber = pageNumber;
}
public bool IsSearchable { get; set; }
public string SearchTerms { get; set; }
public void Search()
{
ReadPackages();
OnPropertyChanged(null);
}
public bool ShowPackageSources { get; set; }
public IEnumerable<PackageSource> PackageSources {
get {
foreach (PackageSource packageSource in registeredPackageRepositories.PackageSources.GetEnabledPackageSources()) {
yield return packageSource;
}
if (registeredPackageRepositories.PackageSources.HasMultiplePackageSources) {
yield return RegisteredPackageSourceSettings.AggregatePackageSource;
}
}
}
public PackageSource SelectedPackageSource {
get { return registeredPackageRepositories.ActivePackageSource; }
set {
if (registeredPackageRepositories.ActivePackageSource != value) {
registeredPackageRepositories.ActivePackageSource = value;
ReadPackages();
OnPropertyChanged(null);
}
}
}
}
}