using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using IssueVision.Data.Web;
using IssueVision.Common;
using MVVMPlugin;
namespace IssueVision.ViewModel
{
[ExportPlugin(ViewModelTypes.IssueEditorViewModel, PluginType.ViewModel)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class IssueEditorViewModel : ViewModelBase
{
#region "Private Data Members"
private IIssueVisionModel _issueVisionModel;
private Issue _currentIssueCache;
#endregion "Private Data Members"
#region "Constructor"
public IssueEditorViewModel()
{
_issueVisionModel = PluginCatalogService.Container.GetExportedValue<IIssueVisionModel>();
// set up event handling
_issueVisionModel.GetIssueTypesComplete += _issueVisionModel_GetIssueTypesComplete;
_issueVisionModel.GetPlatformsComplete += _issueVisionModel_GetPlatformsComplete;
_issueVisionModel.GetResolutionsComplete += _issueVisionModel_GetResolutionsComplete;
_issueVisionModel.GetStatusesComplete += _issueVisionModel_GetStatusesComplete;
_issueVisionModel.GetSubStatusesComplete += _issueVisionModel_GetSubStatusesComplete;
_issueVisionModel.GetUsersComplete += _issueVisionModel_GetUsersComplete;
// set _currentIssueCache to null
_currentIssueCache = null;
// load issue type entries
IssueTypeEntries = null;
_issueVisionModel.GetIssueTypesAsync();
// load platform entries
PlatformEntries = null;
_issueVisionModel.GetPlatformsAsync();
//load resolution entries
ResolutionEntriesWithNull = null;
_issueVisionModel.GetResolutionsAsync();
// load status entries
StatusEntries = null;
_issueVisionModel.GetStatusesAsync();
// load substatus entries
SubstatusEntriesWithNull = null;
_issueVisionModel.GetSubStatusesAsync();
// load user entries
UserEntries = null;
UserEntriesWithNull = null;
_issueVisionModel.GetUsersAsync();
// register for EditIssueMessage
AppMessages.EditIssueMessage.Register(this, OnEditIssueMessage);
}
#endregion "Constructor"
#region "ICleanup interface implementation"
public override void Cleanup()
{
if (_issueVisionModel != null)
{
// unregister all events
_issueVisionModel.GetIssueTypesComplete -= _issueVisionModel_GetIssueTypesComplete;
_issueVisionModel.GetPlatformsComplete -= _issueVisionModel_GetPlatformsComplete;
_issueVisionModel.GetResolutionsComplete -= _issueVisionModel_GetResolutionsComplete;
_issueVisionModel.GetStatusesComplete -= _issueVisionModel_GetStatusesComplete;
_issueVisionModel.GetSubStatusesComplete -= _issueVisionModel_GetSubStatusesComplete;
_issueVisionModel.GetUsersComplete -= _issueVisionModel_GetUsersComplete;
_issueVisionModel = null;
}
// set properties back to null
CurrentIssue = null;
IssueTypeEntries = null;
PlatformEntries = null;
ResolutionEntriesWithNull = null;
StatusEntries = null;
SubstatusEntriesWithNull = null;
UserEntries = null;
UserEntriesWithNull = null;
// unregister any messages for this ViewModel
base.Cleanup();
}
#endregion "ICleanup interface implementation"
#region "Public Properties"
private Issue _currentIssue;
public Issue CurrentIssue
{
get { return _currentIssue; }
private set
{
if (!ReferenceEquals(_currentIssue, value))
{
_currentIssue = value;
RaisePropertyChanged("CurrentIssue");
}
}
}
private IEnumerable<byte> _priorityEntries;
public IEnumerable<byte> PriorityEntries
{
get
{
if (_priorityEntries == null)
{
var priorityList = new List<byte>();
for (var i = IssueVisionServiceConstant.HighestPriority; i <= IssueVisionServiceConstant.LowestPriority; i++)
{
priorityList.Add(i);
}
_priorityEntries = priorityList.AsEnumerable();
}
return _priorityEntries;
}
}
private IEnumerable<byte> _severityEntries;
public IEnumerable<byte> SeverityEntries
{
get
{
if (_severityEntries == null)
{
var severityList = new List<byte>();
for (var i = IssueVisionServiceConstant.HighestSeverity; i <= IssueVisionServiceConstant.LowestSeverity; i++)
{
severityList.Add(i);
}
_severityEntries = severityList.AsEnumerable();
}
return _severityEntries;
}
}
private IEnumerable<IssueType> _issueTypeEntries;
public IEnumerable<IssueType> IssueTypeEntries
{
get { return _issueTypeEntries; }
private set
{
if (!ReferenceEquals(_issueTypeEntries, value))
{
_issueTypeEntries = value;
RaisePropertyChanged("IssueTypeEntries");
}
}
}
private IEnumerable<Platform> _platformEntries;
public IEnumerable<Platform> PlatformEntries
{
get { return _platformEntries; }
private set
{
if (!ReferenceEquals(_platformEntries, value))
{
_platformEntries = value;
RaisePropertyChanged("PlatformEntries");
}
}
}
private IEnumerable<Resolution> _resolutionEntriesWithNull;
public IEnumerable<Resolution> ResolutionEntriesWithNull
{
get { return _resolutionEntriesWithNull; }
private set
{
if (!ReferenceEquals(_resolutionEntriesWithNull, value))
{
_resolutionEntriesWithNull = value;
RaisePropertyChanged("ResolutionEntriesWithNull");
}
}
}
private IEnumerable<Status> _statusEntries;
public IEnumerable<Status> StatusEntries
{
get { return _statusEntries; }
private set
{
if (!ReferenceEquals(_statusEntries, value))
{
_statusEntries = value;
RaisePropertyChanged("StatusEntries");
}
}
}
private IEnumerable<SubStatus> _substatusEntriesWithNull;
public IEnumerable<SubStatus> SubstatusEntriesWithNull
{
get { return _substatusEntriesWithNull; }
private set
{
if (!ReferenceEquals(_substatusEntriesWithNull, value))
{
_substatusEntriesWithNull = value;
RaisePropertyChanged("SubstatusEntriesWithNull");
}
}
}
private IEnumerable<User> _userEntries;
public IEnumerable<User> UserEntries
{
get { return _userEntries; }
private set
{
if (!ReferenceEquals(_userEntries, value))
{
_userEntries = value;
RaisePropertyChanged("UserEntries");
}
}
}
private IEnumerable<User> _userEntriesWithNull;
public IEnumerable<User> UserEntriesWithNull
{
get { return _userEntriesWithNull; }
private set
{
if (!ReferenceEquals(_userEntriesWithNull, value))
{
_userEntriesWithNull = value;
RaisePropertyChanged("UserEntriesWithNull");
}
}
}
#endregion "Public Properties"
#region "Public Commands"
private RelayCommand<DragEventArgs> _handleDropCommand;
public RelayCommand<DragEventArgs> HandleDropCommand
{
get
{
if (_handleDropCommand == null)
{
_handleDropCommand = new RelayCommand<DragEventArgs>(
OnHandleDropCommand,
e => CurrentIssue != null);
}
return _handleDropCommand;
}
}
private void OnHandleDropCommand(DragEventArgs e)
{
try
{
// get a list of files as FileInfo objects
var files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
if (files != null)
{
// loop through the list and read each file
foreach (var file in files)
{
using (var fs = file.OpenRead())
using (var ms = new MemoryStream())
{
fs.CopyTo(ms);
// and then add each file into the Files entity collection
CurrentIssue.Files.Add(
new Data.Web.File
{
FileID = Guid.NewGuid(),
IssueID = CurrentIssue.IssueID,
FileName = file.Name,
Data = ms.GetBuffer()
});
}
}
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
private RelayCommand _addFileCommand;
public RelayCommand AddFileCommand
{
get
{
if (_addFileCommand == null)
{
_addFileCommand = new RelayCommand(
OnAddFileCommand,
() => CurrentIssue != null);
}
return _addFileCommand;
}
}
private void OnAddFileCommand()
{
try
{
if (!_issueVisionModel.IsBusy)
{
FileInfo addedFile = null;
// ask user for a file to add
AppMessages.OpenFileMessage.Send(
new NotificationMessageAction<FileInfo>("Open File", g => addedFile = g));
if (addedFile != null)
{
using (var fs = addedFile.OpenRead())
using (var ms = new MemoryStream())
{
fs.CopyTo(ms);
// and then add the file into the Files entity collection
CurrentIssue.Files.Add(
new Data.Web.File
{
FileID = Guid.NewGuid(),
IssueID = CurrentIssue.IssueID,
FileName = addedFile.Name,
Data = ms.GetBuffer()
});
}
}
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
private RelayCommand<Data.Web.File> _removeFileCommand;
public RelayCommand<Data.Web.File> RemoveFileCommand
{
get
{
if (_removeFileCommand == null)
{
_removeFileCommand = new RelayCommand<Data.Web.File>(
OnRemoveFileCommand,
g => g != null);
}
return _removeFileCommand;
}
}
private void OnRemoveFileCommand(Data.Web.File g)
{
try
{
if (!_issueVisionModel.IsBusy)
{
CurrentIssue.Files.Remove(g);
_issueVisionModel.RemoveFile(g);
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
private RelayCommand<Data.Web.File> _saveToDiskCommand;
public RelayCommand<Data.Web.File> SaveToDiskCommand
{
get
{
if (_saveToDiskCommand == null)
{
_saveToDiskCommand = new RelayCommand<Data.Web.File>(g =>
{
if (!_issueVisionModel.IsBusy)
{
AppMessages.SaveFileMessage.Send(g);
}
}, g => g != null);
}
return _saveToDiskCommand;
}
}
private RelayCommand _addAttributeCommand;
public RelayCommand AddAttributeCommand
{
get
{
if (_addAttributeCommand == null)
{
_addAttributeCommand = new RelayCommand(
OnAddAttributeCommand,
() => CurrentIssue != null);
}
return _addAttributeCommand;
}
}
private void OnAddAttributeCommand()
{
if (!_issueVisionModel.IsBusy)
{
CurrentIssue.Attributes.Add(
new Data.Web.Attribute
{
ID = Guid.NewGuid(),
IssueID = CurrentIssue.IssueID,
AttributeName = "Key",
Value = "Value"
});
}
}
private RelayCommand<Data.Web.Attribute> _removeAttributeCommand;
public RelayCommand<Data.Web.Attribute> RemoveAttributeCommand
{
get
{
if (_removeAttributeCommand == null)
{
_removeAttributeCommand = new RelayCommand<Data.Web.Attribute>(g =>
{
if (!_issueVisionModel.IsBusy)
{
CurrentIssue.Attributes.Remove(g);
_issueVisionModel.RemoveAttribute(g);
}
}, g => g != null);
}
return _removeAttributeCommand;
}
}
#endregion "Public Commands"
#region "Private Methods"
private void _issueVisionModel_GetIssueTypesComplete(object sender, EntityResultsArgs<IssueType> e)
{
if (!e.HasError)
{
IssueTypeEntries = e.Results.OrderBy(g => g.Name);
// check whether IssueTypeEntries is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void _issueVisionModel_GetPlatformsComplete(object sender, EntityResultsArgs<Platform> e)
{
if (!e.HasError)
{
PlatformEntries = e.Results.OrderBy(g => g.OS).ThenBy(g => g.OSVersion);
// check whether PlatformEntries is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void _issueVisionModel_GetResolutionsComplete(object sender, EntityResultsArgs<Resolution> e)
{
if (!e.HasError)
{
// create a new resolution list with the first item of null Name
var resolutionList = e.Results.ToList();
resolutionList.Add(new Resolution());
ResolutionEntriesWithNull = resolutionList.OrderBy(g => g.Name).AsEnumerable();
// check whether ResolutionEntriesWithNull is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void _issueVisionModel_GetStatusesComplete(object sender, EntityResultsArgs<Status> e)
{
if (!e.HasError)
{
StatusEntries = e.Results.OrderBy(g => g.StatusID);
// check whether StatusEntries is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void _issueVisionModel_GetSubStatusesComplete(object sender, EntityResultsArgs<SubStatus> e)
{
if (!e.HasError)
{
// create a new substatus list with the first item of null Name
var substatusList = e.Results.ToList();
substatusList.Add(new SubStatus());
SubstatusEntriesWithNull = substatusList.OrderBy(g => g.Name).AsEnumerable();
// check whether SubstatusEntriesWithNull is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void _issueVisionModel_GetUsersComplete(object sender, EntityResultsArgs<User> e)
{
if (!e.HasError)
{
UserEntries = e.Results.OrderBy(g => g.Name);
// create a new user list with the first item of null user name
var userList = e.Results.ToList();
userList.Add(new User());
UserEntriesWithNull = userList.OrderBy(g => g.Name).AsEnumerable();
// check whether UserEntries/UserEntriesWithNull is populated after CurrentIssue
AssignCurrentIssue(null);
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
private void OnEditIssueMessage(Issue editIssue)
{
if (editIssue == null) return;
// check whether this issue is read-only or not
AppMessages.ReadOnlyIssueMessage.Send(editIssue.IsIssueReadOnly());
AssignCurrentIssue(editIssue);
}
/// <summary>
/// Assign edit issue only after all ComboBox are ready
/// </summary>
/// <param name="editIssue"></param>
private void AssignCurrentIssue(Issue editIssue)
{
if (editIssue != null)
{
// this call is coming from OnEditIssueMessage()
if (IssueTypeEntries != null && PlatformEntries != null &&
ResolutionEntriesWithNull != null && StatusEntries != null &&
SubstatusEntriesWithNull != null && UserEntries != null &&
UserEntriesWithNull != null)
{
// if all ComboBox are ready, we set CurrentIssue
CurrentIssue = editIssue;
_currentIssueCache = null;
}
else
_currentIssueCache = editIssue;
}
else
{
// this call is coming from one of the complete event handlers
if (_currentIssueCache != null && IssueTypeEntries != null &&
PlatformEntries != null && ResolutionEntriesWithNull != null &&
StatusEntries != null && SubstatusEntriesWithNull != null &&
UserEntries != null && UserEntriesWithNull != null)
{
// if all ComboBox are ready, we set CurrentIssue
CurrentIssue = _currentIssueCache;
_currentIssueCache = null;
}
}
}
#endregion "Private Methods"
}
}